我的应用程序一次显示大量图像缩略图。目前,我将所有全尺寸图像保存在内存中,只需在UI中缩放图像即可创建缩略图。但是,我宁愿只在内存中保留小缩略图,只在必要时加载全尺寸图像。
我认为这很容易,但与仅缩放UI中的fullsize图像相比,我生成的缩略图非常模糊。
图像是字节数组,没有标题信息。我提前知道大小和格式,所以我可以使用BitmapSource.Create来创建一个ImageSource。
//This image source, when bound to the UI and scaled down creates a nice looking thumbnail
var imageSource = BitmapSource.Create(
imageWidth,
imageHeight,
dpiXDirection,
dpiYDirection,
format,
palette,
byteArray,
stride);
using (var ms = new MemoryStream())
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(imageSource);
encoder.Save(ms);
var bi = new BitmapImage();
bi.BeginInit();
bi.CacheOption = BitmapCacheOption.OnLoad;
//I can't just create a MemoryStream from the original byte array because there is no header info and it doesn't know how to decode the image!
bi.StreamSource = ms;
bi.DecodePixelWidth = 60;
bi.EndInit();
//This thumbnail is blurry!!!
Thumbnail = bi;
}
我猜它是模糊的,因为我首先将它转换为png,但是当我使用BmpBitmapEncoder时,我得到“没有可用的成像组件”错误。在这种情况下,我的图像是Gray8,但我不确定为什么PngEncoder可以解决它,但BmpEncoder不能。
当然,必须先从原始ImageSource创建缩略图,而不必先将其编码为位图格式?我希望BitmapSource.Create让你像BitmapImage类一样指定解码宽度/高度。
修改
最后的答案是使用带有WriteableBitmap的TransformBitmap来创建缩略图并消除原始的全尺寸图像。
var imageSource = BitmapSource.Create(...raw bytes and stuff...);
var width = 100d;
var scale = width / imageSource.PixelWidth;
WriteableBitmap writable = new WriteableBitmap(new TransformedBitmap(imageSource, new ScaleTransform(scale, scale)));
writable.Freeze();
Thumbnail = writable;
答案 0 :(得分:3)
您应该能够从原始版本创建TransformedBitmap:
var bitmap = BitmapSource.Create(...);
var width = 60d;
var scale = width / bitmap.PixelWidth;
var transform = new ScaleTransform(scale, scale);
var thumbnail = new TransformedBitmap(bitmap, transform);
更新:为了最终摆脱原始位图,您可以从TransformedBitmap创建一个WriteableBitmap:
var thumbnail = new WriteableBitmap(new TransformedBitmap(bitmap, transform));