我有一个WPF应用程序,其中包含一组图像列表。目前我正在使用
BitmapImage
和BitmapCacheOption.OnLoad
来加载这些图像。
问题在于,当图像数量很多时,由于图像的大小,RAM使用量会急剧增加。
我该如何创建原始图像的缩略图以显示在列表框中?
它可能需要被缓存,因为在应用程序运行时,目录中的图像文件可能会被删除或修改。
BitmapImage
和BitmapCacheOption.OnLoad
来加载这些图像。
问题在于,当图像数量很多时,由于图像的大小,RAM使用量会急剧增加。
我该如何创建原始图像的缩略图以显示在列表框中?
它可能需要被缓存,因为在应用程序运行时,目录中的图像文件可能会被删除或修改。
// Create source
BitmapImage myBitmapImage = new BitmapImage();
// BitmapImage.UriSource must be in a BeginInit/EndInit block
myBitmapImage.BeginInit();
myBitmapImage.UriSource = new Uri(@"C:\Water Lilies.jpg");
// To save significant application memory, set the DecodePixelWidth or
// DecodePixelHeight of the BitmapImage value of the image source to the desired
// height or width of the rendered image. If you don't do this, the application will
// cache the image as though it were rendered as its normal size rather then just
// the size that is displayed.
// Note: In order to preserve aspect ratio, set DecodePixelWidth
// or DecodePixelHeight but not both.
myBitmapImage.DecodePixelWidth = 200;
myBitmapImage.EndInit();
//
//when you are ready to render the BitmapImage, do:
imageThumb.Source = myBitmapImage;
您可以使用InterpolationMode.HighQualityBicubic
创建不错的缩略图。
Bitmap bitmap = ...
Bitmap thumbBitmap = new System.Drawing.Bitmap(thumbWidth, thumbHeight);
using (Graphics g = Graphics.FromImage(thumbBitmap))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(bitmap, 0, 0, thumbWidth, thumbHeight);
}
BitmapImage
: _ms = new MemoryStream();
thumbBitmap.Save(_ms, ImageFormat.Png);
_ms.Position = 0;
ImageLoaded = true;
//thumb image property of this class, use in binding
public BitmapImage ThumbImage
{
get
{
if (_thumbImage == null && ImageLoaded)
{
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = _ms;
bi.EndInit();
_thumbImage = bi;
}
return _thumbImage;
}
}
byte[] IImageResizer.CreateThumbnailBytes(byte[] originalImage)
{
Image thumbnail = null;
Image tempImage = Image.FromStream(new MemoryStream(originalImage));
int desiredWidth = 160;
int newPixelWidth = tempImage.Width;
int newPixelHeight = tempImage.Height;
if (newPixelWidth > desiredWidth)
{
float resizePercent = ((float)desiredWidth / (float)tempImage.Width);
newPixelWidth = (int)(tempImage.Width * resizePercent) + 1;
newPixelHeight = (int)(tempImage.Height * resizePercent) + 1;
}
Bitmap bitmap = new Bitmap(newPixelWidth, newPixelHeight);
using (Graphics graphics = Graphics.FromImage((Image)bitmap))
{
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.DrawImage(tempImage, 0, 0, newPixelWidth, newPixelHeight);
}
thumbnail = (Image)bitmap;
MemoryStream ms = new MemoryStream();
thumbnail.Save(ms, ImageFormat.Jpeg);
return ms.ToArray();
}
我传入原始图像二进制,并将图像调整大小为大约160px左右。
希望这能有所帮助!
在查看了MSDN之后,我没有找到任何直接的方法来实现这个,但也许你可以每隔一定像素采样图像,并将数据写入新图像,然后清理原始的全尺寸图像。