如何在Windows 10 UWP中复制和调整图像大小

6
我之前使用了http://www.codeproject.com/Tips/552141/Csharp-Image-resize-convert-and-save中的代码来以编程方式调整图像大小。然而,该项目使用的System.Drawing库在Windows 10应用程序中不可用。
我尝试使用Windows.UI.Xaml.Media.Imaging中的BitmapImage类,但似乎不能提供System.Drawing中的功能。
有人成功调整(缩小)Windows 10中的图像大小吗?我的应用程序将处理来自多个来源、不同格式/大小的图像,并且我正在尝试调整实际图像的大小以节省空间,而不是让应用程序将其大小调整以适合显示它的Image
编辑: 我修改了上述链接中的代码,并实现了一个适合我的特定需求的hack。以下是代码:
public static BitmapImage ResizedImage(BitmapImage sourceImage, int maxWidth, int maxHeight)
{
    var origHeight = sourceImage.PixelHeight;
    var origWidth = sourceImage.PixelWidth;
    var ratioX = maxWidth/(float) origWidth;
    var ratioY = maxHeight/(float) origHeight;
    var ratio = Math.Min(ratioX, ratioY);
    var newHeight = (int) (origHeight * ratio);
    var newWidth = (int) (origWidth * ratio);

    sourceImage.DecodePixelWidth = newWidth;
    sourceImage.DecodePixelHeight = newHeight;

    return sourceImage;
}

这种方法似乎可行,但是理想情况下,我希望创建一个新的/拷贝的BitmapImage进行修改并返回。

以下是它的实际效果截图: 调整大小后的截图


标题有误,楼主。虽然你已经有了一种调整图像大小的方法,但你真正想做的是创建原始图像的副本,将副本调整大小,然后返回该副本。 - Brian Driscoll
@BrianDriscoll 我在编辑之前发布了这个问题。编辑添加了调整原始图像大小的代码。我本来想把它作为答案发布,但时间还不够长。但我确实喜欢新标题。谢谢。 - dub stylee
你能否创建一个图像的常量?或者一个私有属性,你可以引用原始图像的副本并使用相同的函数? - aguertin
既然我不需要保留原始图像数据,现在这样就可以了。我只是在考虑未来的泛化,可能会想要返回原始 BitmapImage 的副本而不是修改原始数据。 - dub stylee
1个回答

8

我可能希望返回原始的BitmapImage的副本, 而不是修改原始的。

直接复制 BitmapImage 的方法不太好,但我们可以多次重复使用 StorageFile

如果您只想选择一张图片,显示它,并同时显示原始图片的重新调整大小的版本,则可以将 StorageFile 作为参数传递,如下所示:

public static async Task<BitmapImage> ResizedImage(StorageFile ImageFile, int maxWidth, int maxHeight)
{
    IRandomAccessStream inputstream = await ImageFile.OpenReadAsync();
    BitmapImage sourceImage = new BitmapImage();
    sourceImage.SetSource(inputstream);
    var origHeight = sourceImage.PixelHeight;
    var origWidth = sourceImage.PixelWidth;
    var ratioX = maxWidth / (float)origWidth;
    var ratioY = maxHeight / (float)origHeight;
    var ratio = Math.Min(ratioX, ratioY);
    var newHeight = (int)(origHeight * ratio);
    var newWidth = (int)(origWidth * ratio);

    sourceImage.DecodePixelWidth = newWidth;
    sourceImage.DecodePixelHeight = newHeight;

    return sourceImage;
}

在这种情况下,您只需要调用此任务并像这样显示重新调整大小的图像:
smallImage.Source = await ResizedImage(file, 250, 250);

如果由于某些原因(例如sourceImage可能是修改后的位图,而不是直接从文件加载),您希望保留BitmapImage参数,并将此新图片重新调整大小为另一个图片,则需要先将重新调整大小的图片保存为文件,然后再打开此文件并重新调整大小。


这太棒了,谢谢Grace。有没有办法将BitmapImageIRandomAccessStream放入WriteableBitmapRenderTargetBitmap中,以便对其进行编码为base64字符串?我可以直接使用StorageFile,但由于调整大小的图像不是StorageFile,因此我需要将其转换为不同的数据类型以进行编码。 - dub stylee
最终我改变了整个流程,使用WriteableBitmap代替BitmapImage,这样我就可以得到编码为base64所需的格式。我仍然需要在ResizedImage函数内创建一个BitmapImage以获取原始尺寸,但至少它能正常工作 :) - dub stylee
@dubstylee,你正在正确地做,我找不到将BitmapImage转换为64base字符串的方法。要将IRandomAccessStream转换为WriteableBitmap,可以使用BitmapDecoder,但我认为你已经知道这一点了。 - Grace Feng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接