Convert BitmapImage to SoftwareBitmap in UWP

◇◆丶佛笑我妖孽 提交于 2021-01-29 17:43:17

问题


I need to find out how to convert a BitmapImage object into a SoftwareBitmap in order to save it to a file without losing resolution as I would do with RenderTargetBitmap.

I have the following situation:

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();
    }
}   

I can't use RenderTargetBitmap on ImageControl because my image from url is way bigger than the ImageControl size. With RenderTargetBitmap I would shrink my output to the size of this control.

Is there any workaround to achieve this?


回答1:


I think that since we have the need to save the image locally, we can properly allocate some system resources to save the image stream.

Since we need SoftwareBitmap, we don't have to use BitmapImage as the source of the Image.

Here is my test code:

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;
}

When you need to save image, you can use this 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();
    }
}  

Note.

When we initially use Uri as the image source, the download is done inside the Image. We can't get the image source as source stream, so we can extract the download process to the outside, so that we can control the original data stream.

Best regards.



来源:https://stackoverflow.com/questions/57187147/convert-bitmapimage-to-softwarebitmap-in-uwp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!