2011-01-19 15 views
7

Tengo una aplicación web donde los usuarios pueden cargar imágenes. El problema actual que me estoy encontrando es que las imágenes que se cargan se guardan en la base de datos en el formato original. Esto causa muchos problemas de rendimiento cuando las imágenes se usan en una página web. Utilicé dotTrace para perfilar la aplicación y veo problemas importantes cuando las imágenes se procesan desde la base de datos.C# mvc carga de imágenes redimensionando el lado del servidor

La idea que tengo es cambiar el tamaño de la imagen cuando se carga en el servidor. Tome el siguiente ejemplo que quiero que la aplicación haga cuando el usuario carga una nueva imagen;

  1. usuario carga una imagen
  2. La imagen se está cambiando a un tamaño de 7.500 x 7.500 en píxeles en 72 dpi
  3. La imagen se guarda en la base de datos
  4. archivo original se dispone

La única imagen almacenada es la mencionada anteriormente y la aplicación weba contiene la tecnología para cambiar el tamaño sobre la marcha.

Ya he leído varios temas aquí en SO. Y la mayoría de ellos me señalan en la dirección de ImageMagick. Esta herramienta ya es familiar en mi empresa y se usa en proyectos de PHP. Pero, ¿hay algún envoltorio de C# lanzado bueno y estable para esta herramienta? Ya encontré las herramientas a continuación, pero están en versión Béta, versión Alpha o actualmente no están actualizadas.

ImageMagick.NET

ImageMagick APP

También encontré this tema sobre el SO. En este tema, se proporciona el siguiente ejemplo de código;

private static Image CreateReducedImage(Image imgOrig, Size newSize) 
{ 
    var newBm = new Bitmap(newSize.Width, newSize.Height); 
    using (var newGrapics = Graphics.FromImage(newBm)) 
    { 
     newGrapics.CompositingQuality = CompositingQuality.HighSpeed; 
     newGrapics.SmoothingMode = SmoothingMode.HighSpeed; 
     newGrapics.InterpolationMode = InterpolationMode.HighQualityBicubic; 
     newGrapics.DrawImage(imgOrig, new Rectangle(0, 0, newSize.Width, newSize.Height)); 
    } 

    return newBm; 
} 

En resumen las preguntas que tengo;

  • ¿Hay alguna ventaja en relación con el rendimiento en el ejemplo anterior?
  • ¿Existe un envoltorio C# bueno y confiable para ImageMagick que pueda usar para hacer esto?

¡Cualquier otro buen consejo relacionado con el rendimiento es bienvenido!

+1

http://imageresizing.net es el camino a seguir. Está probado, es confiable y funciona con poca confianza. Maneja una variedad de formatos fácilmente y se puede llamar en una sola línea de código. Biblioteca extremadamente flexible y capaz. –

Respuesta

3

Usamos el último enfoque: no puedo comentar sobre el rendimiento, pero ciertamente simplifica el manejo de las dependencias.

Sin embargo, una cosa a tener en cuenta es que el código anterior es probablemente demasiado simple si sus usuarios pueden cargar imágenes en todo tipo de formatos. La biblioteca subyacente (GDI +) tiene problemas con muchos formatos de color, pero también depende de la versión del sistema operativo. Aquí está el núcleo del código que usamos:

// GDI+ has problems with lots of image formats, and it also chokes on unknown ones (like CMYK). 
// Therefore, we're going to take a whitelist approach. 
// see http://bmpinroad.blogspot.com/2006/04/file-formats-pixel-formats.html 
// also see http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/c626a478-e5ef-4a5e-9a73-599b3b7a6ecc 
PixelFormat format = originalImage.PixelFormat; 

if (format == PixelFormat.Format16bppArgb1555 || 
    format == PixelFormat.Format64bppArgb) 
{ 
    // try to preserve transparency 
    format = PixelFormat.Format32bppArgb; 
} 
else if (format == PixelFormat.Format64bppPArgb) 
{ 
    // try to preserve pre-multiplied transparency 
    format = PixelFormat.Format32bppPArgb; 
} 
else if (format != PixelFormat.Format24bppRgb && format != PixelFormat.Format32bppRgb) 
{ 
    format = PixelFormat.Format24bppRgb; 
} 


// GIF saving is probably still an issue. If we ever need to tackle it, see the following: 
// http://support.microsoft.com/kb/319061 
// http://www.bobpowell.net/giftransparency.htm 
// http://support.microsoft.com/kb/318343 


using (Bitmap newImage = new Bitmap(newSize.Width, newSize.Height, format)) 
{ 
    using (Graphics Canvas = Graphics.FromImage(newImage)) 
    { 
     using (ImageAttributes attr = new ImageAttributes()) 
     { 
      attr.SetWrapMode(WrapMode.TileFlipXY); 

      Canvas.SmoothingMode = SmoothingMode.AntiAlias; 
      Canvas.InterpolationMode = InterpolationMode.HighQualityBicubic; 
      Canvas.PixelOffsetMode = PixelOffsetMode.HighQuality; 
      Canvas.DrawImage(originalImage, new Rectangle(new Point(0, 0), newSize), srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, GraphicsUnit.Pixel, attr); 
      newImage.Save(outputImageStream, originalImage.RawFormat); 
     } 
    } 
} 
+0

Podemos determinar para los clientes con formatos para cargar. La idea es preservar el archivo original cuando se cargan un GIF (debido a las animaciones) y PNG (debido a la transparencia). Todos los otros formatos (principalmente JPG, a veces BMP de TIFF) causará algún problema al usar este enfoque? O el enfoque GDI +? – Rob

+0

Y si quiero establecer el formato de píxel en 72DPI. ¿Cómo puedo conseguir esto? ¿Qué formato usar? – Rob

+1

El objeto Bitmap (newImage en este caso) tiene propiedades HorizontalResolution y VerticalResolution que puede modificar para establecer los píxeles por pulgada. GIF podría ser más difícil. Tendrá que lidiar con la transparencia y volver a dibujar la imagen con su paleta de colores original; consulte los enlaces en los comentarios del código. Para las animaciones, creo que podría recorrer los fotogramas de la imagen utilizando originalImage.SelectActiveFrame(), pero no lo he probado, ni estoy seguro de cómo podría recombinar los cuadros una vez que haya hecho eso. –

2

Nunca utilicé ImageMagic, pero he usado las funciones de cambio de tamaño de la imagen GDI +, incluso en un sitio que genera y cambia el tamaño de más de 100.000 imágenes al día sin problemas de rendimiento.

Yo diría que usar los métodos GDI + está bien. No se preocupe por envolver una herramienta o marco externo.

+0

Actualmente tratando de implementar una buena solución usando GDI +. Te avisaremos de los resultados – Rob

+0

Los métodos GDI están bien, siempre y cuando [dispongas de todo en las cláusulas using() {} y evites los 25+ errores] (http://nathanaeljones.com/163/20-image-resizing -pitfalls /). –

1

He usado ImageGen en los sitios de Umbraco. (Ciertamente no está relacionado con Umbraco, es bueno para cualquier aplicación ASP.NET, simplemente sucedió que algunos de los paquetes de Umbraco que estaba usando lo requerían). Es fácil de usar, y es posible que pueda salirse con la suya gratis. versión ...

Cuestiones relacionadas