首页 文章

创建图像的缩略图并将其存储在缓存中

提问于
浏览
5

我有一个WPF应用程序,它有一个列表框的图像 . 现在我使用BitmapImage和BitmapCacheOption.OnLoad来加载图像 . 问题在于,当存在大量图像时,由于图像的大小,RAM使用天空火箭 . 如何创建要在列表框中显示的原件缩略图?它可能必须缓存,因为我可以在应用程序运行时删除或修改目录中的映像文件 .

4 回答

  • 4

    这是我不久前写的一种可能对你有帮助的方法 .

    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左右 .

    希望能帮助到你!

  • 2

    您可以使用 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;
            }
        }
    
  • 0

    在检查MSDN后,我没有看到任何直接的方法来做到这一点,但也许你可以只是每隔这么多像素采样图像并将数据写入新图像,然后清理完整尺寸的图像 .

  • 2

    问题在于,当存在大量图像时,由于图像的大小,RAM使用天空火箭 .

    来自的C#示例:http://msdn.microsoft.com/en-us/library/ms748873.aspx

    // 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;
    

    请注意DecodePixelWidth和DecodePixelHeight属性,以便以所需的缩小像素大小缓存图像 . 使用两者来拉伸图像以适合缩略图大小 .

相关问题