问题
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