jueves, 10 de diciembre de 2009

C# Redimensionar imágenes



El problema del tamaño de las imágenes cada vez es menor con las actuales velocidades de conexión y anchos de banda... depende, que nos lo digan cuando estamos con un 3G.

Es por ello que es preciso subir las imágenes a internet a un tamaño que conserve lo mejor posible la calidad pero que reduzca en gran medida el peso de las originales obtenidas con las magníficas cámaras actuales de más de 5 megapíxeles (incluidas ya en muchos móviles).

Para ello sólo tenemos que obtener un programa de diseño gráfico, seleccionar la foto, hacer un redimensionado al tamaño que consideremos adecuado, seleccionar un tipo de interpolación, y hecho.

¿Pero qué sucede cuando tenemos centenares de fotos para reducir? Pues una a una se convierte en un árduo trabajo. Existen programas comerciales que permiten ejecutar en batch este tipo de transformaciones, aunque algunos suelen ser difíciles de configurar. Seguramente también existen multitud de proyectos open source que lo permiten, pero ya sabemos cómo va esto del open source, nos podemos estar peleando un buen rato para decidir qué proyecto utilizar, y realmente, para algo tan sencillo, creo que vale la pena que lo hagamos nosotros solos.

Para ello sólo tenemos que hacernos un pequeño programita, en este caso en C#, que por un lado permita seleccionar el directorio dónde está el conjunto de fotos a transformar y las recorra una a una, solicite a un método la transformación, y grabe la imagen resultado con una variación del nombre.

Aquí os dejo el código para redimensionar la imagen, utilizando una interpolación bicúbica de alta calidad, y trabajando con imágenes en formato jpeg. El resto del programita sabréis hacerlo perfectamente.



public static Image ResizeImage
(Image srcImage, int newWidth, int newHeight)
{
using (Bitmap imagenBitmap =
new Bitmap(newWidth, newHeight, PixelFormat.Format32bppRgb))
{
imagenBitmap.SetResolution(
Convert.ToInt32(srcImage.HorizontalResolution),
Convert.ToInt32(srcImage.HorizontalResolution));

using (Graphics imagenGraphics =
Graphics.FromImage(imagenBitmap))
{
imagenGraphics.SmoothingMode =
SmoothingMode.AntiAlias;
imagenGraphics.InterpolationMode =
InterpolationMode.HighQualityBicubic;
imagenGraphics.PixelOffsetMode =
PixelOffsetMode.HighQuality;
imagenGraphics.DrawImage(srcImage,
new Rectangle(0, 0, newWidth, newHeight),
new Rectangle(0, 0, srcImage.Width, srcImage.Height),
GraphicsUnit.Pixel);
MemoryStream imagenMemoryStream = new MemoryStream();
imagenBitmap.Save(imagenMemoryStream, ImageFormat.Jpeg);
srcImage= Image.FromStream(imagenMemoryStream);
}
}
return srcImage;
}


Pero voy a ser bueno y os lo voy a dejar aquí para que os lo descarguéis.

Redimensionar Imágenes con C#

¡Que os sea de utilidad!

6 comentarios:

  1. gracias loco, andaba buscando la forma de reducir el tamanio de las fotos para subirlas a internet, te agradezo!

    ResponderEliminar
  2. Te agredezco un montón!!! Yo también andaba buscando como reducir tamaño y calidad. Una consulta: ¿Cómo lograste darle esa apariencia a tu programa?? Está muy bueno!!

    ResponderEliminar
  3. Me alegra que os haya servido.

    Tened en cuenta que toda reducción implícitamente acarrea una pérdida de calidad que dependiendo del algoritmo, será mayor o menor. C#, y con ello este ejemplo que os dejo, implementa el método de interpolación bicúbica tal y como lo implementa por ejemplo Paint Shop Pro o Photoshop.

    En cuanto a la apariencia del programa se basa en las librerías DotNetBar de Microsoft, que son una serie de controles UI que permiten mejorar la apariencia visual e incrementar la usabilidad del software.

    Un saludo

    ResponderEliminar
  4. Bueno, todo esto puede estar muy bien, pero tiene algunos aspectos que habría considerar muy en serio.

    En primer lugar, si tu sitio no tiene muchas imágenes que subir puede ser una buena opción; pero, ¿qué ocurre cuando las imágenes que se suben pueden ser varias al mismo tiempo? Imagínate que un gran portal con un gran número de usuarios (tipo facebook, flicker, o wordpress, por poner algunos ejemplos) tuvieran que redimensionar las imágenes que le llegan cada minuto. Por muchos servidores que tuvieras, el sistema se colapsaría. Si te das cuenta, todos ellos cuentan con programas, scripts, etc. que trabajan en lado cliente. Si tengo una imagen del móvil de 2 Mb, no tengo que esperar 10 minutos a que el archivo suba; no tengo que redimensionarla previamente con un programa específico. Simplemente el programa trabaja en el lado servidor (nada de ActiveX, ni ningún complemento que pueda hacer que el usuario desconfíe), y en unos segundos tengo la imagen subida, lista para retocar, etc.

    Además, si tengo una conexión lenta, se puede exceder el límite de tiempo de espera (Session TimeOut), y cuando llevo un buen rato esperando a cargar la imagen, me puede desplegar el típico: 'El tiempo de conexión ha caducado', con lo cual estarás espantando a tus visitantes.

    Por otra parte, los recursos que destina el servidor mientras se sube la imagen y la procesa suelen ser muy grandes, sobre todo si tienes muchos visitanes y las imágenes se suben muy a menudo, con el riesgo que corres de colapsar el servidor y los problemas que ello conlleva....

    Actualmente la tecnología nos provee de herramientas que pueden trabajar en el lado cliente sin mermar su privacidad, sin avisos de ActiveX o los ya obsoletos applets de Java. Estas herramientas nos ofrecen en este caso la posibilidad de redimensionar las imágenes en el propio ordenador del usuario en segundo, antes de subirlas, transformarlas en archivos relativamente pequeños, subirlas más rapidamente y sin malgastar recursos en servidores propios.

    Las ventajas que conlleva este sistema son evidentes:

    1º - La imagen se procesa en el ordenador del cliente, con lo cual no utilizamos la memoria del servidor.

    2º - La imagen generada es más pequeña en tamaño, por lo que el cliente tarda mucho menos en enviarla al servidor. Además, la velocidad de subida es alrededor de un 10% la de bajada.

    3º - Mientras el archivo (php, asp, jsp, etc) que está recibiendo las imágenes, está ralentizando el sistema, sobre todo si son varios los usuarios que están accediendo al mismo recurso.

    En definitiva, si tienes pocos clientes en el servidor puede ser un recurso aceptable (si quien envía las imágenes no tiene problema en esperar unos minutos a que suban), pero hoy en día existen soluciones que, por las razones que he mencionado, son las que el gran público reclama.

    No deja de ser una opinión personal, pero a medida que avanzan las tecnologías la gente se acostumbra a la potencialidad de los grandes portales y exigen lo mismo de los demás. Lo contrario es quedarse atrás y los visitantes buscarán mejores soluciones que, por supuesto, existen.

    Un Saludo.

    ResponderEliminar
  5. Estimado Arturo,

    Das un repaso interesante a la problemática de la gestión de las imágenes en sitios de publicación masiva.

    Aunque posiblemente confudí al lector al intentar transmitir el objetivo de este artículo, que no es más que para aquellos que alguna vez hemos tenido que subir gran cantidad de fotos a un sitio web, como por ejemplo para un pintor al que para empezar se tiene que subir toda su obra a su página Web, igual nos resulta más sencillo realizar una pequeña aplicación como la anterior que ni siquiera plantearnos el buscar alternativas. Cuenta que muchas veces la productividad se pierde evaluando alternativas ante una decisión con a penas implicaciones.

    Por último, me gustaría invitarte, si te parece correcto, a presentarte y a escribir un artículo sobre esas tecnologías actuales que comentas para la reducción del tamaño de las fotografías en el lado del cliente, ya que es algo muy interesante que nos gustaría compartir con nuestros lectores.

    Agradezco tu comentario y espero que te animes con mi invitación.

    Un cordial saludo

    ResponderEliminar
  6. Francisco: Considera el siguiente problema, Institución de salud sin grandes recursos de banda ancha, un equipo nuevo de radiología con imágenes digitalizadas. Especialistas a 4 horas en automóvil.
    ¿Como abordarías el desarrollo de una aplicación que dividiera las imágenes en 10 partes simetricas para ser enviadas una por una por Internet, esperar la décima y el mismo programa integrar de nuevo la imagen. Gracias por tu atención

    ResponderEliminar