Importante: Junto con este artículo y el anterior (Subir archivos al servidor/base de datos), recomiendo leer un artículo más nuevo: Redimensionar y guardar imágenes en ASP.NET, con el cual se resuelven algunos detalles de este.
Como dije en mi último post, si vamos a permitir que el usuario suba imágenes en una aplicación, hay que tener controlado el tamaño de dichas imágenes. Dejar que los usuarios suban imágenes de cualquier tamaño es muy riesgoso, tanto en sobrecarga de información en el servidor de almacenamiento como en la transferencia de datos en la red (local o Internet).
Tampoco podemos ponernos estrictos con el usuario y decirle «la imagen debe ser máximo de 320×240», o algo así. No todos somos diseñadores. No todos tenemos Fireworks, Photoshop, Paint.NET o algún programa para modificar imágenes. Lo mejor es que nosotros mismos hagamos ese ajuste a las imágenes, una vez que el usuario las haya subido y antes de guardarlas en nuestro servidor.
Retomando el ejemplo del artículo anterior, modificaremos el método GuardarArchivo
:
private void GuardarArchivo(HttpPostedFile file) { // Se carga la ruta física de la carpeta temp del sitio string ruta = Server.MapPath("~/temp"); // Si el directorio no existe, crearlo if (!Directory.Exists(ruta)) Directory.CreateDirectory(ruta); string archivo = String.Format("{0}\\{1}", ruta, file.FileName); // Se usará un objeto Image para guardar la imagen cargada Image img = RedimensionarImagen(file.InputStream); // Verificar que el archivo no exista if (File.Exists(archivo)) MensajeError(String.Format( "Ya existe una imagen con nombre\"{0}\".", file.FileName)); else { // Se revisa el formato de la imagen string ext = file.ContentType.Substring( file.ContentType.LastIndexOf("/") + 1); ImageFormat format; switch (ext){ case "gif": format = ImageFormat.Gif; break; case "bmp": format = ImageFormat.Bmp; break; case "png": format = ImageFormat.Png; break; default: format = ImageFormat.Jpeg; break; } img.Save(archivo, format); } }
El objeto System.Drawing.Image
(hay que tener cuidado con no confundirlo con el control en System.Web.UI.WebControls
) también tiene su método para guardar una imagen en disco, aunque es algo más complicado. Tenemos que revisar el tipo de imagen para indicar el formato con el que se va a guardar. En caso de ser un formato que no tenemos enlistado (como TIF, por ejemplo), se convertirá a JPEG.
Lo siguiente es definir el método RedimensionarImagen:
private static Image RedimensionarImagen(Stream stream) { // Se crea un objeto Image, que contiene las propiedades de la imagen Image img = Image.FromStream(stream); // Tamaño máximo de la imagen (altura o anchura) const int max = 200; int h = img.Height; int w = img.Width; int newH, newW; if (h > w && h > max) { // Si la imagen es vertical y la altura es mayor que max, // se redefinen las dimensiones. newH = max; newW = (w * max) / h; } else if (w > h && w > max){ // Si la imagen es horizontal y la anchura es mayor que max, // se redefinen las dimensiones. newW = max; newH = (h * max) / w; } else { newH = h; newW = w; } if (h != newH && w != newW) { // Si las dimensiones cambiaron, se modifica la imagen Bitmap newImg = new Bitmap(img, newW, newH); Graphics g = Graphics.FromImage(newImg); g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear; g.DrawImage(img, 0, 0, newImg.Width, newImg.Height); return newImg; } else return img; }
Existe un método GetThumbnailImage
en la clase Image
, pero no lo recomiendo, ya que de entrada, crea imágenes de muy mala calidad (para que se den una idea, es peor que guardar una imagen en formato JPEG en el MS Paint o.O), además de que requiere ciertos parámetros más complejos. Usar la clase Graphics
nos permite redimensionar la imagen bajo un modo de interpolación a nuestra elección, y aunque se ve muy complejo, se basa en operaciones sencillas.
El objeto devuelto es una imagen con unas dimensiones estándares. También podríamos definir las dimensiones máximas como parámetros, o como variables configurables, o de cualquier otro modo, pero eso ya depende de cada quien.
muy buen aporte gracias
está excelente, sólo le agregaría que valide el residuo para ver si le aumenta un pixel, bueno comparando el calculo a como redimensiona Photoshop 🙂
a ok ya vi alojar el resultado en el dato entero hace el trabajo 🙂
Lo quiero traducir a VB.NET pero me quedo en la primera linea
private static Image RedimensionarImagen(Stream stream)
pues aunque coloco Imports System.Drawing no me aparece el tipo stream … no encuentro cual es el error o que debo imports. Ya lo agregue como referencia tambien a system.drawing
Olvidenlo ya lo solucione, gracias.
y como lo solucionaste ?
Hola Cesar, estoy con lo mismo que tú, subir y redimensionar imágenes usando ASP.NET y VB.NET, podrías mandarme el código de la rutina RedimensionarImage(). Mi correo es antonio@siinet.com
Muchas gracias
y como seria en vb.net???
Hola, probe tu codigo, me funciono correctamente, el detalle que vi, es que una imagen en png de 1366 x 768 pixeles que pesa 118KB, al reducir el tamaño lo hace correctamente, pero el peso de la imagen quedo en: 143KB subio,
esto sera correcto?
Cómo estás, me podrás enviar el código completo por mail a lucascristalli@gmail.com? Gracias!!