Tengo una aplicación WPF que tiene un cuadro de lista de imágenes. En este momento estoy usando BitmapImage y BitmapCacheOption.OnLoad para cargar las imágenes. El problema es que cuando hay muchas imágenes, el uso de RAM se dispara debido al tamaño de las imágenes. ¿Cómo puedo crear imágenes en miniatura de los originales para mostrar en el cuadro de lista? Probablemente deba almacenarse en caché, ya que los archivos de imagen en el directorio pueden eliminarse o modificarse mientras la aplicación se está ejecutando.Crear miniaturas de imágenes y almacenarlas en caché
Respuesta
Se pueden crear mapas de bits pulgar decente utilizando 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);
}
Si va a crear los pulgares en un subproceso de fondo simplemente guardarlos en una secuencia de memoria que luego se puede utilizar con pereza para crear el BitmapImage
cuando se le solicite:
_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;
}
}
Después de consultar MSDN, no veo ninguna manera directa de hacerlo, pero tal vez podría simplemente muestrear la imagen cada tantos píxeles y escribir los datos en una nueva imagen, y luego limpiar la de tamaño completo.
Aquí hay un método que escribí no hace mucho tiempo que puede ser de ayuda.
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();
}
Paso en las imágenes originales en binario, y cambio el tamaño de la imagen para que sea aproximadamente 160px.
Espero que ayude!
El problema es que cuando hay muchas imágenes, el uso de RAM se dispara debido al tamaño de las imágenes.
C# ejemplo a partir de: 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;
Nota las propiedades DecodePixelWidth y DecodePixelHeight a caché de la imagen en el tamaño de píxel reducido deseado. Use ambos para estirar la imagen para que se ajuste al tamaño de la miniatura.
- 1. Almacenamiento de imágenes y miniaturas en s3 en django
- 2. Cómo subir imágenes al servidor Php y almacenarlas en phpmyadmin
- 3. SDWebImage redimensionar/escalar/recortar las imágenes procedentes de la url antes de almacenarlas en caché
- 4. ¿Genera miniaturas de imágenes en ASP.NET?
- 5. Almacenamiento en caché de imágenes en Memcached
- 6. Crear miniaturas y reducir el tamaño de la imagen
- 7. Android, cómo cargar imágenes de la URL y almacenarlas de forma persistente en el widget de la galería?
- 8. ¿La manera más eficiente de crear miniaturas?
- 9. ¿UIImageView imágenes de caché?
- 10. ¿Una forma elegante de crear miniaturas de imágenes almacenadas en s3 con ec2 y comunicarse con los rieles al finalizar?
- 11. ¿Cómo crear miniaturas o previsualizar videos?
- 12. Adición small_image y de miniaturas programación
- 13. Cómo capturar miniaturas de imágenes Y guardar archivos en una carpeta personalizada en Android
- 14. Creación de miniaturas en ImageMagick/GraphicsMagick
- 15. Crear imágenes en miniatura de forma dinámica (usando django)
- 16. Cómo almacenar imágenes en caché y archivos html en PhoneGap
- 17. Expiración de caché en imágenes estáticas
- 18. ¿Es una buena idea usar filestream para almacenar imágenes y miniaturas?
- 19. crear miniaturas de grandes películas con FFmpeg lleva demasiado tiempo
- 20. Miniaturas de video en Java
- 21. HTML5 iPhone caché dinámico de imágenes
- 22. Miniaturas FLV
- 23. ¿Cómo crear miniaturas/capturas de pantalla de archivos PDF en mi servidor Linux?
- 24. Creación de miniaturas para video en iOS
- 25. Crear/modificar imágenes en JavaScript
- 26. Miniaturas de imagen de CSS puro
- 27. miniaturas en PDF en Delphi
- 28. Activar caché de imágenes en modo desarrollo en Rails 3.1
- 29. Cargando imágenes grandes como miniaturas sin problemas de memoria en Java?
- 30. regeneración de miniaturas usando paperclip gema
¡Estupendo! Esto hace que cargar las imágenes sea mucho más rápido en mi aplicación y no es necesario que maneje cada imagen en tamaño completo y luego vuelva a escalarla. – ygoe