2010-12-31 22 views
5

イメージのリストボックスを持つWPFアプリケーションがあります。今は、BitmapImageとBitmapCacheOption.OnLoadを使ってイメージをロードしています。問題は、たくさんの画像がある場合、RAMの使用量が画像のサイズのためにロケットになることです。リストボックスに表示するオリジナルのサムネイル画像を作成するにはどうすればよいですか?アプリケーションの実行中に、ディレクトリ内のイメージファイルが削除または変更される可能性があるため、キャッシュされている可能性があります。イメージのサムネイルを作成し、キャッシュに保存します。

答えて

2

_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を確認した後では、これを行う簡単な方法はありませんが、非常に多くのピクセルごとにイメージをサンプリングして新しいイメージに書き込んだり、フルサイズのイメージをクリーンアップしたりできます。要求されたときにあなたがバックグラウンドスレッドで親指を作成している場合は、単にあなたがなまけBitmapImageを作成するために使用できるメモリストリームに保存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); 
    } 

を使用してまともな親指のビットマップを作成することができます

2

これはあまりにもずっと前にあなたが手伝ってくれた方法です。

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程度にイメージのサイズを変更します。

希望すると助かります!

4

問題は、画像がたくさんある場合、画像のサイズによってRAMの使用空が大きく変化することです。 DecodePixelWidthとDecodePixelHeight特性が所望の低減された画素サイズの画像をキャッシュする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; 

注:から

C#の例。両方を使用してサムネイルサイズに合わせて画像を伸ばします。

+0

素晴らしい!これにより、アプリケーションの読み込み速度が大幅に向上し、フルサイズで各画像を処理してから再度スケールダウンする必要はありません。 – ygoe

関連する問題