2009-08-04 15 views
5

To jest mój pierwszy dzień z Silverlight. Próbuję prototypować aplikację, która (między innymi funkcjami) powinna mieć możliwość zmiany rozmiaru obrazów dostarczonych przez użytkownika. Powinien być w stanie obsłużyć i wyświetlić jednocześnie kilka rozmiarów obrazów. Najbardziej oczywiste podejścia, które wypróbowałem, wydają się "przeciekać" pamięć w tym sensie, że oryginalne bitmapy wciąż są przywoływane w pewien sposób, co powoduje, że Silverlight przydziela setki megabajtów pamięci po pewnym czasie. Po prostu chcę móc ładować obrazy jeden po drugim, zmieniać ich rozmiar i zachować małe wersje.Zmiana rozmiaru obrazów w Silverlight 3 przy użyciu WriteableBitmap

Aby być precyzyjnym, próbowałem następujące:

  • Tworzenie listy System.Windows.Controls.Image „s (i ich skalowania). Nie dziwię się, że to nie zadziałało.

  • Tworzenie listy prostokątów wypełnionych pędzlami. Ja też się nie dziwię.

  • Renderowanie bitmap w System.Windows.Media.Imaging.WriteableBitmap. Spodziewałem się, że to się uda; Zakładałem, że bitmapy są po prostu rysowane bezpośrednio i nie są w żaden sposób przywoływane. Jednak zużycie pamięci wskazywało inaczej.

Oto fragment właściwego kawałka kodu:

// create image source 
Stream stream = file.OpenRead(); 
BitmapImage bmpImg = new BitmapImage(); 
bmpImg.SetSource(stream); 
stream.Close(); 

// create temporary image from it 
Image tmpImg = new Image(); 
tmpImg.Source = bmpImg; 

// this is required by WriteableBitmap 
tmpImg.Measure(new Size(100, 100)); 
tmpImg.Arrange(new Rect(0, 0, 100, 100)); 

// prepare scaling to 100x100 
ScaleTransform scaleTrans = new ScaleTransform(); 
double scale = (double)100/(double)Math.Max(bmpImg.PixelHeight, bmpImg.PixelWidth); 
scaleTrans.CenterX = 0; 
scaleTrans.CenterY = 0; 
scaleTrans.ScaleX = scale; 
scaleTrans.ScaleY = scale; 

// render 
WriteableBitmap writeableBitmap = new WriteableBitmap(100, 100); 
writeableBitmap.Render(tmpImg, scaleTrans); 
writeableBitmap.Invalidate(); 

// final image 
Image img = new Image(); 
img.Source = writeableBitmap; 

Mam nadzieję, że nie brakuje niczego głupiego, ale wygląda na OK, aby mnie i robi to, co trzeba (z wyjątkiem problem z pamięcią). Należy również pamiętać, że jakość kodu nie powinna być jakością produkcji; to tylko szybki i brudny prototyp.

Zauważyłem, że nie jestem sam; Znalazłem pytania dotyczące manipulacji obrazem w Silverlight. Jestem również świadomy faktu, że mogłem użyć biblioteki innej firmy, przetwarzać na serwerze lub napisać coś nawet samemu, ale jestem zaskoczony, że Silverlight nie oferuje żadnych podstawowych funkcji manipulacji obrazem. Nie wydaje się to rzadkim wymaganiem, biorąc pod uwagę położenie samego Silverlight.

+1

Ogólnie ludzie są przy użyciu bibliotek takich jak kod FJCore w http://code.google.com/p/fjcore/ do teraz, aby wypełnić tę lukę w międzyczasie. Twój ostatni akapit, w którym oferujesz pozycję/oświadczenie na temat Silverlight, umniejsza to pytanie. –

Odpowiedz

1

Nie znam szczegółów, ale jeśli nie masz dostępu do zasobów - możesz sprawdzić, który obiekt implementuje interfejs IDisposable. Domyślam się, że klasy Stream i Image implementują ten interfejs. A jeśli tak - wywołanie na nich Dispose() lub zawijanie ich użycia w instrukcji "Using" spowoduje natychmiastowe uwolnienie ich zasobów, zamiast czekać, aż w końcu zacznie działać odśmiecacz.

4

Czy spojrzałeś na WriteableBitmapEx project? Jest to projekt typu open source z wieloma metodami rozszerzenia dla klasy WriteableBitmap. Oto jak zmienić rozmiar:

BitmapImage image = new BitmapImage(); 
image.SetSource(dialog.File.OpenRead()); 

WriteableBitmap bitmap = new WriteableBitmap(image); 
WriteableBitmap resizedBitmap = bitmap.Resize(500, 500, WriteableBitmapExtensions.Interpolation.Bilinear); 

// For uploading 
byte[] data = resizedBitmap.ToByteArray(); 
Powiązane problemy