30 de junio de 2015

BMPs con fondos transparentes

Artículo original: BMPs with Transparent Backgrounds
http://weblogs.foxite.com/vfpimaging/archive/2007/10/24/5190.aspx
Autor: Cesar Ch.
Traducido por: Luis María Guayán


Aquí están algunas notas sobre BMPs transparentes en VFP, basadas en algunas conclusiones que tomé después de varios debates en Foxite, especialmente aquellos con Bernard Bout.

Los archivos de imágenes BMP, cuando se utilizan en la propiedad Picture de un control Image, suelen mostrar los blancos (RGB (255,255,255)) como transparente. VFP crea una máscara temporal para las imágenes a fin de mostrarlas de esta manera.

Imagen 1: Los BMPs pueden tener los blancos convertidos a transparentes cuando se lo utiliza en la propiedad "Picture" y se configura "BackStyle" en "Transparente".

Pero esto sólo funciona para la propiedad PICTURE, NO para PICTUREVAL!

El siguiente código crea una simple imagen sobre la marcha, y la guarda en disco. La imagen de la izquierda utiliza la propiedad PICTURE, y la derecha utiliza PICTUREVAL.

IMPORTANTE

Requiere VFP9 y GdiPlusX para funcionar.

¡Por favor asegúrese que tiene la última versión!

http://www.codeplex.com/VFPX/Wiki/View.aspx?title=GDIPlusX&referringTitle=Home

PUBLIC oForm
oForm = NEWOBJECT("form1")
oForm.Show
RETURN
 
DEFINE CLASS form1 AS form
   Top = 13
   Left = 17
   Height = 168
   Width = 314
   DoCreate = .T.
   Caption = "Testing PictureVal rendering"
   Name = "Form1"

ADD OBJECT image1 AS image WITH ;
   BackStyle = 0, ;
   Height = 120, ;
   Left = 24, ;
   Top = 24, ;
   Width = 120, ;
   Name = "Image1"

ADD OBJECT image2 AS image WITH ;
   BackStyle = 0, ;
   Height = 120, ;
   Left = 168, ;
   Top = 24, ;
   Width = 120, ;
   Name = "Image2"

PROCEDURE Init
   DO LOCFILE("System.prg")
   LOCAL loBmp as xfcBitmap
   LOCAL loGfx as xfcGraphics
   WITH _Screen.System.Drawing 
      loBmp = .Bitmap.New(60, 60, 0, .Imaging.PixelFormat.Format24bppRGB)
      loGfx = .Graphics.FromImage(loBmp)
      loGfx.Clear(.Color.White)
      loGfx.DrawRectangle(.Pen.New(.Color.Red, 3), 10,10,40,40)
      loBmp.Save("c:\tempBMP.bmp", .Imaging.ImageFormat.Bmp)
   ENDWITH
   Thisform.Image1.Picture = "c:\tempBMP.bmp"
   Thisform.Image2.PictureVal = FILETOSTR("c:\tempBMP.bmp")
ENDPROC

ENDDEFINE

Imagen 2: Los BMPs muestran el BLANCO como transparentes sólo cuando se utiliza la propiedad "Picture". Cuando se utiliza la propiedad "PictureVal", se muestra sin una máscara transparente.

La imagen de la izquierda utiliza la propiedad Picture, y la de la derecha utiliza la propiedad PictureVal de la forma más sencilla: FILETOSTRING("c:\MyPicture.Bmp")

Esto nos demuestra que, lamentablemente, no podemos obtener transparencias en BMPs utilizando la propiedad PictureVal.

Afortunadamente en VFP9 SP2, el Equipo VFP corrigió el problema con las presentación de lo PNG, y podemos usar nuestros archivos PNGs con los objetos Image de VFP. Pero en este caso, la necesidad de establecer manualmente el canal Alpha, especificando que color (o colores) se convertiran en transparente.

Con GdiPlusX estas cosas se vuelven realmente fáciles. Solo una línea hará el truco:

This.oBmp.MakeTransparent(.Color.White)

Reemplace el código del procedimiento INIT() de arriba, con el que se muestra abajo, que solo cambia a la prestación PNG, y utiliza el método "MAKETRANSPARENT" de la libreria xfcBitmap GdiPlusX:

PROCEDURE Init
   DO LOCFILE("System.prg")
   LOCAL loBmp as xfcBitmap
   LOCAL loGfx as xfcGraphics
   WITH _Screen.System.Drawing 
      loBmp = .Bitmap.New(60, 60) && The default is 32bppARGB
      loGfx = .Graphics.FromImage(loBmp)
      loGfx.Clear(.Color.White)
      loGfx.DrawRectangle(.Pen.New(.Color.Red, 3), 10,10,40,40)
      loBmp.MakeTransparent(.Color.White)
      loBmp.Save("c:\tempPNG.png", .Imaging.ImageFormat.Png)
   ENDWITH
   Thisform.Image1.Picture = "c:\tempPNG.png"
   Thisform.Image2.PictureVal = FILETOSTR("c:\tempPNG.png")
ENDPROC

Imagen 3: Los PNGs permiten el uso de los canales Alpha, de modo que las transparencias están disponibles tanto para las propiedades Picture y PictureVal.

¿Esto es suficiente?

Aun no es suficiente para Bernard - Parte 1

Como él dijo en un hilo de Foxite: "VFP tiene un problema refrescando PNGs de un tamaño razonable. Hacen "Flash". El mejor formato para usar con VFP es BMP". - TOTALMENTE CIERTO - Bah!. Esto es muy fácil de reproducir, crear cualquier formulario, poner un objeto imagen dentro del mismo, utilizando cualquier imagen PNG. Luego, agregue otra imagen, pero esta vez utilizar un BMP. Configurar las propiedades Anchor, ejecutar el formulario y cambiar su tamaño para comprender lo que ocurre. Tal vez para la gran mayoría de las personas esto es aceptable, pero con BMPs podemos tener un buen resultado.

Aun no es suficiente para Bernard - Parte 2

El observo que los BMPs se originaron a partir de los ejemplos que he venido utilizando con GDI+ y no podría haber convertido sus BLANCOS a TRANSPARENTES cuando se utilizan en el control Imagen.

!#*$¨*&¨($%+)(*#$%&(_*%¨#)&*(¨#&*()YUIOH%&*_#(*&%(_*#$¨

La verdad es que él había reportado esto el año pasado, cuando creé un ejemplo para su fabuloso ONE NOTE TABS - VFP -X GDI+ code samples for "Recreating One Note Tabs in VFP9" from Bernard

Él acaba de traer este tema otra vez en un hilo reciente de Foxite, y finalmente me tomé el tiempo para hacer algunas nuevas pruebas, y encontré el problema.

En la mayoria de casos, cuando creé mis bitmaps desde cero, usé el método xfcBitmap.Create(), exactamente como esto:

LOCAL loBmp as xfcBitmap
loBmp = .Bitmap.New(lnWidth, lnHeight)

Esto crea por defecto un mapa de bits con las dimensiones lnWidth X lnHeight, con 32bppARGB PixelFormat. Esto significa que para cada píxel del mapa de bits se utilizan 32bits, o 4 bytes, para ROJO, VERDE, AZUL y ALPHA (transparencia).

¡Pero los BMPs no soportan transparencias!

De esta manera, el byte ALFA es totalmente inútil para el caso de BMPs, haciendo nuestro archivo un 25% más grande...

El mayor problema es que VFP no transforma BLANCOS de Bitmaps de 32bppARGB en transparente!!!

Así, creando un mapa de bit que será guardado con el formato de imagen BMP, NUNCA use 32bppARGB. ¡Use en cambio 24bppRGB! Y este definitivamente soluciona nuestro problema, y Bernard será capaz de continuar desarrollando sus obras maestras de su diseño, con esperanza, usando GdiPlusX.

En lugar de:

loBmp = .Bitmap.New(lnWidth, lnHeight)

Uso:

loBmp = .Bitmap.New(60, 60, 0, .Imaging.PixelFormat.Format24bppRGB)

¡Gracias Bernard! Esto fue una buena lección para mí, he aprendido varias cosas buenas en esta investigación. Muy gentil, ya que esto trae algunas nuevas posibilidades para varios de los nuevos controles.

El control GdiPlusX ImageCanvas también recibirá algunas modificaciones, lo que permite interpretar en modo de archivo, guardando en archivos TMP, pero utilizando 24bppRGB, para permitir las transparencias. Otra modificación que hemos acordado, es agregar un modo de interpretar PNG, ya que los PNGs permiten el uso del canal alfa.

VFPPaint también ha sido actualizado, y permite a los usuarios elegir entre 24bppRGB (nuevo valor por omisión) y 32bppARGB.


No hay comentarios. :

Publicar un comentario