在 UWP 中将 BitmapImage 转换为 SoftwareBitmap

Convert BitmapImage to SoftwareBitmap in UWP

我需要了解如何将 BitmapImage 对象转换为 SoftwareBitmap,以便将其保存到文件中而不丢失分辨率,就像我对 RenderTargetBitmap 所做的那样。

我有以下情况:

private void TakePic() {
    BitmapImage currentImage = new BitmapImage(new Uri("http://.../image.jpg"));
    ImageControl.Source = currentImage;
}

private void SavePic() {
    StorageFile file = await folder.CreateFileAsync(...);
    using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
    {
        BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
        encoder.SetSoftwareBitmap();
        await encoder.FlushAsync();
    }
}   

我无法在 ImageControl 上使用 RenderTargetBitmap,因为我在 url 中的图像比 ImageControl 大得多。使用 RenderTargetBitmap,我会将输出缩小到此控件的大小。

是否有任何解决方法可以实现此目的?

我觉得既然我们有把图片保存到本地的需求,那么可以适当分配一些系统资源来保存图片流。

因为我们需要SoftwareBitmap,所以我们不必使用BitmapImage作为图像的来源。

这是我的测试代码:

SoftwareBitmap CacheBitmap = null;

public TestPage()
{
    this.InitializeComponent();
    SetImageSource();
}

public async void SetImageSource()
{
    // Load image from web
    WebRequest myrequest = WebRequest.Create("http://.../image.jpg");
    WebResponse myresponse = myrequest.GetResponse();
    var imgstream = myresponse.GetResponseStream();

    // Try to create SoftwareBitmap
    MemoryStream ms = new MemoryStream();
    imgstream.CopyTo(ms);
    var decoder = await BitmapDecoder.CreateAsync(ms.AsRandomAccessStream());
    var softBitmap = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8,BitmapAlphaMode.Premultiplied);

    // Use SoftwareBitmapSource to ImageSource
    var source = new SoftwareBitmapSource();
    await source.SetBitmapAsync(softBitmap);
    TestImage.Source = source;

    // Keep reference
    CacheBitmap = softBitmap;
}

当你需要保存图片时,可以使用这个SoftwareBitmap:

private void SavePic() {
    StorageFile file = await folder.CreateFileAsync(...);
    using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
    {
        BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
        encoder.SetSoftwareBitmap(CacheBitmap);
        await encoder.FlushAsync();
    }
}  

注意。

当我们最初使用Uri作为图片源时,下载是在Image内部完成的。我们无法获取图片源作为源流,所以我们可以将下载过程提取到外部,这样我们就可以控制原始数据流了。

此致。