java 生成缩略图并返回字节数组,直接从无标题的图像字节数组创建缩略图

My application shows a large number of image thumbnails at once. Currently, I am keeping all full size images in memory, and simply scaling the image in the UI to create the thumbnail. However, I'd rather just keep small thumbnails in memory, and only load the fullsize images when necessary.

I thought this would be easy enough, but the thumbnails I'm generating are terribly blurry compared to just scaling the fullsize image in the UI.

The images are byte arrays with no header information. I know the size and format ahead of time, so I can use BitmapSource.Create to create an 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;

}

I'm guessing its blurry since I'm converting it to png first, but when I use the BmpBitmapEncoder I get that "No imaging component available" error. In this case my image is Gray8, but I'm not sure why the PngEncoder can figure it out but the BmpEncoder can't.

Surely there must be someway to create a thumbnail from the original ImageSource without having to encode it to a bitmap format first? I wish BitmapSource.Create just let you specify a decode width/height like the BitmapImage class does.

EDIT

The final answer is to use a TransformBitmap with a WriteableBitmap to create the thumbnail and eliminate the original, full-size image.

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;

解决方案

You should be able to create a TransformedBitmap from the original one:

var bitmap = BitmapSource.Create(...);

var width = 60d;

var scale = width / bitmap.PixelWidth;

var transform = new ScaleTransform(scale, scale);

var thumbnail = new TransformedBitmap(bitmap, transform);

UPDATE: In order to get ultimately rid of the original bitmap, you could create a WriteableBitmap from the TransformedBitmap:

var thumbnail = new WriteableBitmap(new TransformedBitmap(bitmap, transform));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值