Marca de Agua
Objetivo
Para esta entrada se marcan dos objetivos diferentes con las marcas de agua:- Se desea conseguir, en función a una imagen origen, una imagen destino con una marca de agua que será otra imagen.
- Se desea conseguir, en función de una imagen origen, una imagen destino con una marca de agua al pie que será un texto. Por ejemplo el Copyright.
Marca de Agua con Imagen
Esta marca de agua estará creada por otra imagen. Es decir, se fusionarán 2 imágenes diferentes en 1. Para conseguirlo habrá que aprovechar el GDI de .NET, las librerías gráficas de las que dispone .NET. Con este ejemplo, la marca de agua resultante estará centrada.
Librerías
- System.Drawing;
- System.Drawing.Imaging;
- System.Drawing.Drawing2D;
Clases
- Image: Funciones y propiedades de imágenes (abrir, guardar, etc)
- BitMap: Mapa de Bits.
- Graphics: Se emplea para “pintar”
Procedimiento
- Inicialmente se cargan las dos imágenes, la imagen origen y la que actuará como marca de agua.
- A continuación, crear un BitMap que servirá como lienzo en el que “pintar” la nueva imagen.
- Creamos un objeto Graphic asociado al BitMap.
- A continuación, pintar la imagen original con la función ‘DrawImage’ del objeto Graphic. Se debe especificar el ancho y alto de la imagen. Previamente se pueden especificar efectos de suavizado.
- Después seleccionar las posiciones para la marca de agua.
- Lo siguiente será pintar la marca de agua con el objeto graphics en la posición calculada. Se puede (se debe) aplicar transparencia a la imagen con los atributos de la imagen y una matriz de transparencia.
- Finalmente pasar el Bitmap a un objeto imagen y guardar la imagen con el formato que se desee. Descargamos de memoria los objetos Image y Graphics.
Código
/// ----------------------------------------------------------------------------- ////// Genera una imagen con una marca de agua que es otra imagen. /// /// Ruta de la imagen original /// Ruta de la imagen que servirá de marca de agua /// Ruta de la imagen final con la marca de agua ////// [fcortes] 01/06/2012 10:55:10 /// /// ----------------------------------------------------------------------------- public bool marcaAguaImagen(string rutaImgOrig, string rutaMarca, string rutaImgDest, bool transparencia) { bool exito = true; Image imgPhoto = null; Image imgWatermark = null; try { // Cargamos la foto original imgPhoto = Image.FromFile(rutaImgOrig); // Cargamos la imagen de la marca de agua imgWatermark = new Bitmap(rutaMarca); } catch (Exception ex) { exito = false; } if (exito) { // Obtenemos ancho y alto de la foto int phWidth = imgPhoto.Width; int phHeight = imgPhoto.Height; //Creamos un nuevo mapa de bits con el ancho y alto de la imagen origen Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb); //bmPhoto.SetResolution(72, 72); // Obtenemos el objeto graphics del mapa de bits bmPhoto. Graphics grPhoto = Graphics.FromImage(bmPhoto); int wmWidth = imgWatermark.Width; int wmHeight = imgWatermark.Height; // Suavizado de contorno grPhoto.SmoothingMode = SmoothingMode.AntiAlias; // Pintamos la imagen de origen grPhoto.DrawImage( imgPhoto, new Rectangle(0, 0, phWidth, phHeight), 0, 0, phWidth, phHeight, GraphicsUnit.Pixel); // Atributos para la marca de agua (por si deseamos cambiar la transparencia etc) ImageAttributes imageAttributes = new ImageAttributes(); //Si deseamos transparencia if (transparencia) { float[][] colorMatrixElements = { new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f}, new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f}, new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f}, new float[] {0.0f, 0.0f, 0.0f, 0.3f, 0.0f}, new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f} }; ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements); imageAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); } // Posicion centrada de la marca de agua int xPosOfWm = (phWidth / 2) - (wmWidth / 2); int yPosOfWm = (phHeight / 2) - (wmHeight / 2); // Pintamos la marca de agua en nuestro mapa de bits. grPhoto.DrawImage(imgWatermark, new Rectangle(xPosOfWm, yPosOfWm, wmWidth, wmHeight), 0, 0, wmWidth, wmHeight, GraphicsUnit.Pixel, imageAttributes); // Vamos a cambiar la imagen por lo que la sacamos de memoria antes imgPhoto.Dispose(); // Pasamos el bitmap a un Image para aprovecharnos de sus propiedades imgPhoto = bmPhoto; // Descargamos de memoria el graphics grPhoto.Dispose(); // Guardamos la imagen imgPhoto.Save(rutaImgDest, ImageFormat.Jpeg); imgPhoto.Dispose(); imgWatermark.Dispose(); } return exito; }
Marca de Agua Texto
Esta marca de agua estará creada por un texto, fusionando 1 imagen con texto. Para conseguirlo habrá que aprovechar el GDI de .NET, las librerías gráficas de las que dispone .NET. La marca de agua resultante estará centrada.
Librerías
- System.Drawing;
- System.Drawing.Imaging;
- System.Drawing.Drawing2D;
Clases
- Image: Funciones y propiedades de imágenes (abrir, guardar, etc)
- BitMap: Mapa de Bits.
- Graphics: Se emplea para “pintar”
Procedimiento
- Cargar la imagen.
- A continuación, crear un BitMap que servirá como lienzo en el que “pintar” la nueva imagen.
- Crear un objeto Graphic asociado al BitMap.
- Encontrar tamaño de letra que maximiza el ancho.
- Seleccionar laposición en la que pintar las letras. Usar un align center para facilitar algo las cosas.
- Pintar dos veces las letras usando el método de Graphics ‘DrawString’. Se deben usar dos Brush diferentes (dos pinceles) y uno de los 'draw' realizarlo un pixel en X e Y más adelantado. Con esto último conseguimos efecto sombreado.
- Finalmente pasar el Bitmap a un objeto imagen y guardar la imagen con el formato que se desee. Descargar de memoria los objetos Image y Graphics.
Código
/// ----------------------------------------------------------------------------- ////// Genera una imagen con una marca de agua que es un texto (Copyright) /// /// Ruta de la imagen original /// Texto que deseamos escribir /// Ruta de la imagen de destino ////// [fcortes] 01/06/2012 11:08:56 /// /// ----------------------------------------------------------------------------- public bool marcaAguaTexto(string rutaImgOrig, string textoMarca, string rutaImgDest) { bool exito = true; // Cargamos la foto original Image imgPhoto = Image.FromFile(rutaImgOrig); // Obtenemos ancho y alto de la foto int phWidth = imgPhoto.Width; int phHeight = imgPhoto.Height; Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb); //bmPhoto.SetResolution(72, 72); Graphics grPhoto = Graphics.FromImage(bmPhoto); grPhoto.SmoothingMode = SmoothingMode.AntiAlias; grPhoto.DrawImage( imgPhoto, new Rectangle(0, 0, phWidth, phHeight), 0, 0, phWidth, phHeight, GraphicsUnit.Pixel); //To maximize the size of the Copyright message we will test 7 different Font sizes // to determine the largest possible size we can use for the width of our Photograph. int[] sizes = new int[] { 16, 14, 12, 10, 8, 6, 4 }; Font crFont = null; SizeF crSize = new SizeF(); for (int i = 0; i < 7; i++) { crFont = new Font("arial", sizes[i], FontStyle.Bold); crSize = grPhoto.MeasureString(textoMarca, crFont); if ((ushort)crSize.Width < (ushort)phWidth) break; } // Posición abajo centrada int yPixlesFromBottom = (int)(phHeight * .05); float yPosFromBottom = ((phHeight - yPixlesFromBottom) - (crSize.Height / 2)); float xCenterOfImg = (phWidth / 2); // Pintamos dos veces con el graphics el texto en la imagen con dos brush diferentes // con esto conseguiremos el efecto de sombra. StringFormat StrFormat = new StringFormat(); StrFormat.Alignment = StringAlignment.Center; SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(153, 0, 0, 0)); grPhoto.DrawString(textoMarca, crFont, semiTransBrush2, new PointF(xCenterOfImg + 1, yPosFromBottom + 1), StrFormat); SolidBrush semiTransBrush = new SolidBrush( Color.FromArgb(153, 255, 255, 255)); grPhoto.DrawString(textoMarca, crFont, semiTransBrush, new PointF(xCenterOfImg, yPosFromBottom), StrFormat); // Vamos a cambiar la imagen por lo que la sacamos de memoria antes imgPhoto.Dispose(); // Pasamos el bitmap a un Image para aprovecharnos de sus propiedades imgPhoto = bmPhoto; // Descargamos de memoria el graphics grPhoto.Dispose(); // Guardamos la imagen imgPhoto.Save(rutaImgDest, ImageFormat.Jpeg); imgPhoto.Dispose(); return exito; }
Comentarios
Publicar un comentario