2010-12-31 19 views
5

Görüntülerin bir liste kutusuna sahip bir WPF uygulamasına sahibim. Şu anda görüntüleri yüklemek için BitmapImage ve BitmapCacheOption.OnLoad kullanıyorum. Sorun, görüntülerin büyüklüğünden dolayı RAM kullanım gökyüzü roketleri bir sürü resim olduğunda. Liste kutusunda görüntülenecek asılların küçük resimlerini nasıl oluşturabilirim? Uygulama çalışırken dizindeki görüntü dosyaları silinebileceği veya değiştirilebileceğinden muhtemelen önbelleğe alınması gerekir.Görüntülerin küçük resimlerini oluşturun ve önbelleğinde saklayın

cevap

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'i denetledikten sonra bunu yapmak için herhangi bir doğrudan yöntem görmüyorum, ancak belki de her görüntüyü çok sayıda piksele örnekleyebilir ve verileri yeni bir görüntüye yazdırabilir ve sonra da tam boyutu birincisi temizleyebilirsiniz. istendiğinde Sen bir arka plan iş parçacığı başparmak oluşturuyorsanız sadece o tembel BitmapImage oluşturmak için kullanabileceğiniz bir bellek akışı içine kaydedebilirsiniz 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); 
    } 

kullanarak iyi başparmak bitmap oluşturamazsınız

2

Çok uzun zaman önce yazmayla ilgili size yardımcı olabilecek bir yöntem.

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(); 
    } 

Orijinal resimlerden ikili olarak geçiyorum ve görüntünün yaklaşık 160 piksel boyutunda olmasını sağladım.

Umut eder!

4

Sorun, görüntülerin büyüklüğünden dolayı RAM kullanımı gökyüzü roketleri çok fazla görüntü olduğunda ortaya çıkıyor. DecodePixelWidth ve DecodePixelHeight özellikleri arzu edilen düşük piksel boyutunda görüntü önbelleğe 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; 

Not: 'den

C# örneği. Resmi küçük resim boyutuna sığacak şekilde genişletmek için ikisini de kullanın.

+0

Harika! Bu, uygulamada görüntülerin çok daha hızlı yüklenmesini sağlıyor ve her görüntüyü tam boyutta işlememeye ve daha sonra tekrar tekrar ölçeklendirmeye ihtiyacım yok. – ygoe

İlgili konular