2009-08-04 26 views
5

Questo è il mio primo giorno con Silverlight. Sto provando a prototipare un'applicazione che (tra le altre funzioni) dovrebbe essere in grado di ridimensionare le immagini fornite dall'utente. Dovrebbe essere in grado di gestire e visualizzare più immagini ridimensionate contemporaneamente. Gli approcci più ovvi che ho provato sembrano "perdere" la memoria nel senso che le bitmap originali vengono ancora referenziate in qualche modo, il che fa sì che Silverlight assegni dopo qualche istante centinaia di megabyte di memoria. Voglio solo essere in grado di caricare le immagini una per una, ridimensionarle e mantenere le versioni piccole.Ridimensionamento delle immagini in Silverlight 3 utilizzando WriteableBitmap

Per essere precisi, ho provato la seguente:

  • Creazione di un elenco di System.Windows.Controls.Image 's (e loro ridimensionamento). Non sono sorpreso che questo non ha funzionato.

  • Creazione di un elenco di rettangoli riempiti da pennelli immagine. Neanche io sono sorpreso.

  • Rendering dei bitmap in System.Windows.Media.Imaging.WriteableBitmap. Mi aspettavo che questo funzionasse bene; Supponevo che le bitmap fossero in realtà disegnate direttamente e non referenziate in alcun modo. Tuttavia, il consumo di memoria indicato diversamente.

Ecco un frammento del pezzo rilevante di codice:

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

spero non mi manca niente stupido, ma sembra a OK per me e fa la cosa giusta (ad eccezione del problema di memoria). Si tenga inoltre presente che la qualità del codice non dovrebbe essere una qualità di produzione; è solo un prototipo veloce e sporco.

Ho notato che non sono solo; Ho trovato domande relative alla manipolazione delle immagini in Silverlight. Sono anche consapevole del fatto che potrei utilizzare alcune librerie di terze parti, eseguire l'elaborazione sul server o scrivere qualcosa anche da solo, ma sono sorpreso che Silverlight non offra alcuna funzione di manipolazione delle immagini di base. Non sembra essere un requisito raro dato dove Silverlight si posiziona.

+1

In generale le persone stanno usando le librerie come ad esempio il codice FJCore a http://code.google.com/p/fjcore/ per ora di colmare questa lacuna nel frattempo. Il tuo paragrafo finale in cui offri una posizione/affermazione su Silverlight toglie la domanda. –

risposta

1

Non conosco le specifiche qui, ma se stai perdendo risorse, potresti guardare quale dei tuoi oggetti implementa l'interfaccia IDisposable. Direi che le classi Stream e Image implementano questa interfaccia. E se lo fanno - chiamando Dispose() su di loro (o avvolgendo il loro uso in un'istruzione "Using"), faranno in modo che liberino le loro risorse immediatamente piuttosto che aspettare che il garbage collector possa dare il via alla fine.

4

Hai guardato il WriteableBitmapEx project? È un progetto open source con una tonnellata di metodi di estensione per la classe WriteableBitmap. Ecco come si ridimensiona:

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(); 
Problemi correlati