Colabora .NET

Enmarcador de Imágenes

[GDI con imágenes, rectángulos y lienzos]

 

Fecha: 04/Jul/2006 (30-Junio-2006 )
Autor: Ewing Morales - ([email protected])

Puntúa este artículo en Panorama

 


Uno de mis pasatiempos favoritos es la fotografía, y como a cualquier fotógrafo, me gusta imprimir mis mejores fotos con el objetivo de mostrarlas a mis amigos y familiares (ya saben, no siempre anda uno con la laptop en todos lados... pero el papel, es fácil de cargar).

Bueno, como les decía, siempre que llevo a imprimir mis fotos me gusta ponerles un margen, para darles una apariencia un poco mas profesional y que resalte la composición. Este margen o marco siempre se los pongo a mis fotografías con Photoshop y bueno, no falta decirles lo que me tardo en definir el marco para cada foto.

Para evitar esta inversión de tiempo, he buscado en la red alguna aplicación gratuita y sencilla para crear estos marcos, y como pueden notar, no he podido hallar una aplicación que pueda convencerme debido a que el tipo de marco que a mi me gusta, normalmente no lo traen definido (casi siempre cuentan con márgenes de colores o patrones demasiado vistosos y que por supuesto se ven de cualquier manera menos profesionales).

Otra cosa que aprendí al imprimir mis fotografías, es que para que una foto digital en formato 3x2 se imprima con un marco adecuado y parezca una postal, el contenedor de la imagen (lienzo o canvas) debe ser 10% mayor que la imagen misma. Con esto, esto lo he probado en equipo de impresión kodak, fuji, y kioskos de autoservicio de impresión de fotos, en fin, no quiere decir que sea una norma de la industria, pero al menos a mi me ha funcionado. Pero seguro que alguno de ustedes se pregunta porque no solicito la impresión de mis fotos con un margen y ya, la respuesta es que al menos en el lugar donde vivo, solo ponen márgenes blancos y además no hay opción de un borde entre la foto y el margen.

Pero basta de tanta explicación, para que se den una idea de como debe ser la imagen a imprimir y como finalmente las maquinas de impresión las procesan, a continuación les pongo un ejemplo.

Imagen editada, con margen y lista para su impresión fotográfica.
El equipo de impresión recorta (azul) el borde de la fotografía para adaptarlo al papel.

Como puede verse, aun después de que el equipo de impresión hace el recorte de la fotografía (lo cual en este ejemplo esta exagerado para que se distinga fácilmente) el efecto que se deseaba permanece, esto gracias a que el lienzo es 10% más grande que la fotografía.

Y por no encontrar en la red una aplicación que pudiera cumplir con esta adecuación de manera sencilla, me decidí a crear una pequeña (por el momento) aplicación que me facilitara la tarea, me permitiera ahorrar tiempo y además me ayudara a poner en practica algunas cosillas que quería trabajar de la GDI (el motor gráfico de los sistemas Windows de Microsoft).

La aplicación (picture Framer)

El concepto de la aplicación es sencillo, realmente su parte importante es la función que adecua la imagen original a un nuevo canvas o lienzo, le pone el borde (línea) y le define el margen (o fondo general).

A continuación, el código en VB.Net de la misma además de unas importantes variables globales:

Dim imgOrig As Image
Dim imgBmp As Bitmap
Dim canvas As Graphics
Dim coordX, coordY As Integer
Dim estiloBorde As Pen
Dim porcentajeDeMargen As Double

Private Sub actualizaImgMod()
    Try
        porcentajeDeMargen = AnchoMargen.Value / 100.0
        imgBmp = New Bitmap(imgOrig.Width + CInt(imgOrig.Width * porcentajeDeMargen), _
			imgOrig.Height + CInt(imgOrig.Height * porcentajeDeMargen))
        canvas = Graphics.FromImage(imgBmp)
        canvas.FillRectangle(New SolidBrush(ColorMargen.BackColor), 0, 0, imgBmp.Width, imgBmp.Height)

        coordX = Math.Floor((imgBmp.Width - imgOrig.Width) / 2)
        coordY = Math.Floor((imgBmp.Height - imgOrig.Height) / 2)

        estiloBorde = New Pen(ColorBorde.BackColor, AnchoBorde.Value)

        canvas.DrawImage(imgOrig, coordX, coordY, imgOrig.Width, imgOrig.Height)
        canvas.DrawRectangle(estiloBorde, coordX, coordY, imgOrig.Width, imgOrig.Height)

        PicBoxMod.Image = imgBmp

		estiloBorde.Dispose()
		canvas.Dispose()
		GC.Collect()

    Catch ex As Exception
        'Nothing
    End Try
End Sub 

Que es lo que puede observarse en el código:

1. Antes que nada, definimos que el "porcentaje de margen" debe calcularse de acuerdo al valor ingresado en nuestro formulario, por defecto es 10%, como comentábamos anteriormente.
2. Ahora, antes de trabajar con un objeto graphics (es decir el lienzo) debemos definir el espacio que le corresponde, y como en este caso, siempre es mas sencillo definirlo a partir de un bitmap (un bitmap se crea de forma rápida, ancho y alto y ya esta, jaja).
3. Después definimos el lienzo a partir del bitmap creado (con esto hacemos un lienzo que pueda contener al bitmap) y ahora el lienzo esta listo para pintar en el lo que querramos, pero antes le ponemos un color de fondo, y este color de fondo es realmente el color del margen, o lo que es lo mismo, es la parte que no se pinta una vez que se coloca la imagen y el borde (línea).
4. Calculamos nuestras coordenadas a partir de las cuales quedara definida la imagen, todo esto con el objetivo de centrarla, por supuesto. Así mismo, definimos el tipo de borde que queremos ponerle, básicamente es una línea sólida y del color elegido en el formulario.
5. Pintamos en el lienzo la imagen original (noten que si tiene transparencias, las transparencias se respeta, yo he probado con pngs).
6. Pintamos un rectángulo no relleno, es decir, solo el borde del mismo, sobre la imagen, creando como puede verse en el ejemplo, la línea alrededor de la misma.
7. Nuestra "pintura" (graphics) se la asociamos al Picture Box designado para contener la imagen modificada. Finalmente liberamos y colectamos memoria no útil.

Súper sencillo, ¿no es cierto? Ya con eso le hemos puesto margen a nuestra imagen seleccionada, y no se deben de olvidar de llamar a esta función cada vez que modifique el valor en alguno de los parámetros importantes.

Al guardar la imagen, asígnenle un nombre y la extensión para la que viene definida nuestra aplicación es JPG, para la cual, aun cuando definimos a través de un encoder que no queremos perder calidad (es decir la guardamos con 100% de calidad), definitivamente perdemos algo, poquito eso si.

¿Que es lo que sigue?

Por el momento solo tenemos la posibilidad de asignar el tipo de marco definido a una sola imagen, pero no se requiere demasiado cambio para hacer que este proceso afecte en bloque a todas las imágenes de un directorio, o porque no, mejorar la interfaz para que luzca algo similar al picasa. En fin, este solo es el primer paso.

Nota:
El programa ha sido creado con Visual Studio 2005.


Espacios de nombres usados en el código de este artículo:

System.Drawing.Imaging

 


Código de ejemplo (ZIP):

 

Fichero con el código de ejemplo: ewing_picture_framer.zip - 158 KB

(MD5 checksum: [8186F380304BA042B92DB42B7169A84D])

 


ir al índice principal del Guille