【问题标题】:Convert BitmapImage to SoftwareBitmap in UWP在 UWP 中将 BitmapImage 转换为 SoftwareBitmap
【发布时间】:2019-07-25 17:00:43
【问题描述】:

我需要了解如何将 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 我会将输出缩小到此控件的大小。

是否有任何解决方法来实现这一点?

【问题讨论】:

  • 嗨。我注意到您的图像转换的目的是在本地保存图像。然后你可以尝试使用HttpClient下载图片,不需要做图片转换。
  • 这个问题是用户决定保存他在 ImageControl 中预览的图像的那一刻,可能不再存在于服务器中,因为我在服务器上有一个连续的“图像流”和一个允许我在特定时间下载图像的 API。但是,它只允许下载最后 n 秒的图像。如果用户拍摄第 (n + 1) 秒的照片,则它不再可用。我不知道我是否能够解释自己
  • 我知道。所以我可以假设您只有一次机会从链接中获取图像。我理解您为什么要使用SoftwareBitmap,但您似乎对如何将BitmapImage 转换为SoftwareBitmap 有疑问。我可以给出我的解决方案吗?
  • 当然,我会一直听取可能有帮助的解决方案

标签: uwp type-conversion bitmapimage


【解决方案1】:

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

由于我们需要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 内部完成的。我们无法获取图片源作为源流,所以可以将下载过程提取到外部,这样就可以控制原始数据流了。

最好的问候。

【讨论】:

  • 是的!这正是我一直在寻找的!在此之前我遇到的另一个解决方法是在用户拍摄照片后立即将图像保存为名为 temp.jpg 的文件,并在每次拍摄另一张照片时覆盖它。当点击保存时,Temp.jpg 将被重命名为 foo.jpg。无论如何,这个解决方案是完美的。非常感谢您。
猜你喜欢
  • 1970-01-01
  • 2018-02-19
  • 1970-01-01
  • 2017-10-21
  • 1970-01-01
  • 2016-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多