2009-08-04 12 views
5

Este es mi primer día con Silverlight. Estoy tratando de crear un prototipo de una aplicación que (entre otras funciones) debería poder cambiar el tamaño de las imágenes proporcionadas por el usuario. Debe ser capaz de manejar y mostrar varias imágenes redimensionadas a la vez. Los enfoques más obvios que he intentado parecen "filtrar" la memoria en el sentido de que los mapas de bits originales todavía están siendo referenciados de alguna manera, lo que hace que Silverlight asigne cientos de megabytes de memoria después de un tiempo. Solo quiero poder cargar las imágenes una por una, cambiar su tamaño y mantener las versiones pequeñas.Cambiar el tamaño de las imágenes en Silverlight 3 usando WriteableBitmap

Para ser precisos, he intentado lo siguiente:

  • Crear una lista de System.Windows.Controls.Image 's (y extender su aplicación). No me sorprende que esto no haya funcionado.

  • Creación de una lista de rectángulos rellenos por pinceles de imagen. No estoy sorprendido tampoco.

  • Representación de los mapas de bits en System.Windows.Media.Imaging.WriteableBitmap. Esperaba que esto funcionara bien; Supuse que los mapas de bits realmente solo se dibujaban directamente y no se los referenciaba de ninguna manera. Sin embargo, el consumo de memoria indica lo contrario.

Aquí hay un fragmento de la pieza correspondiente de código:

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

espero que no me falta nada tonto, pero parece que bien para mí y hace lo correcto (excepto el problema de memoria). Tenga en cuenta también que la calidad del código no debe ser una calidad de producción; es solo un prototipo rápido y sucio.

Me di cuenta de que no estoy solo; Encontré preguntas relacionadas con la manipulación de imágenes en Silverlight. También soy consciente del hecho de que podría usar una biblioteca de terceros, hacer procesamiento en el servidor o escribir algo, incluso a mí mismo, pero me sorprende que Silverlight no ofrezca ninguna función básica de manipulación de imágenes. No parece ser un requisito poco común dado que Silverlight se posiciona a sí mismo.

+1

En la gente en general están utilizando las bibliotecas, tales como el código de FJCore en http://code.google.com/p/fjcore/ por el momento de llenar este vacío en el ínterin. Su párrafo final en el que ofrece una posición/declaración acerca de Silverlight le resta valor a la pregunta. –

Respuesta

1

No conozco los detalles aquí, pero si está perdiendo recursos, podría ver cuál de sus objetos implementa la interfaz IDisposable. Supongo que las clases Stream e Image implementan esta interfaz. Y si lo hacen, llamar a Dispose() sobre ellos (o envolver su uso en una declaración de "Uso") hará que liberen sus recursos de forma inmediata en lugar de esperar a que el recolector de basura los active eventualmente.

4

¿Has mirado el WriteableBitmapEx project? Es un proyecto de código abierto con una tonelada de métodos de extensión para la clase WriteableBitmap. Así es como se cambia el tamaño:

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(); 
Cuestiones relacionadas