sep 102010
 

Buenas,

Para los que nos gusta más el formato de imagen PNG, con Delphi 2010 estamos de suerte dado que trae «de serie» una unit para manipular este tipo de imágenes, la pngimage (no se si también está en Delphi 2009, si alguien puede confirmármelo, le estaría agradecido). No pretendo explicar dicha unit, pero sí os recomiendo que le deis un vistazo para saber qué podemos hacer con una imagen en este formato.

Lo común en grandes aplicaciones (y no tan grandes) es que haya mucha imagen que se repita. Imaginemos una imagen para un botón de aceptar, ¿en cuantas pantallas tenemos ese botón? En muchas. ¿Y que pasa si en cada una de esas pantallas tenemos que poner la imagen? Por pasar no pasa nada, sencillamente que el exe va aumentando de tamaño «tontamente».

La solución está clara, usar un fichero de recursos que almacene, al menos, las imágenes repetitivas. Crear un fichero de recursos es sencillo, sólo tenemos que crear un archivo de texto con extensión rc y poner tabulado nombre de recursos, tipo de recursos y nombre de la imagen. Dado que no hay un tipo de recurso específico para las imágenes PNG, usaremos el RCDATA.

Un ejemplo de fichero podría ser esto:

RES_IMG_OK_16X     			RCDATA  "btn_16_ok.png"
RES_IMG_CANCEL_16X			RCDATA	"btn_16_cancel.png"
RES_IMG_MAIL_16X			RCDATA	"btn_16_email.png"
RES_IMG_SEARCH_16X			RCDATA	"btn_16_search.png"

Ahora sólo queda compilarlo para crear un archivo de recurso (.res) con el compilador de recursos brcc32.exe (suele estar en el path).

Para usar el nuevo fichero, en la unit que deseemos tenemos que añadir

{$R MisRecursos.res}

Donde MisRecursos.res es el nombre del fichero de recursos.

Ahora que ya tenemos el fichero de recursos creado, tan solo nos quedará añadir las imágenes a nuestros botones o TImages. Con el siguiente par de funciones cargaremos en la propiedad del componente que toque la imagen del fichero de recursos que deseemos

procedure LoadPNGFromResource(Picture: TPicture; const ResName: string); overload;
var
  Png: TPngImage;
begin
  Png := TPngImage.Create;
  try
    Png.LoadFromResourceName(HInstance, ResName);
    Picture.Assign(Png);
  finally
    if Assigned(Png) then  FreeAndNil(Png);
  end;
end;

procedure LoadPNGFromResource(Bitmap: TBitmap; const ResName: string); overload;
var
  Png: TPngImage;
begin
  Png := TPngImage.Create;
  try
    Png.LoadFromResourceName(HInstance, ResName);
    Bitmap.Assign(Png);
  finally
    if Assigned(Png) then  FreeAndNil(Png);
  end;
end;

Y un pequeño ejemplo de llamada

  LoadPNGFromResource(imgImage.Picture, 'RES_IMG_MAIL_16X');
  LoadPNGFromResource(bAccept.Glyph, 'RES_IMG_OK_16X');
  LoadPNGFromResource(bCancel.Glyph, 'RES_IMG_CANCEL_16X');

Para terminar, podemos poner esas dos funciones en una unit a parte y así, donde queramos cargar un PNG del fichero de recursos, sólo tendremos que usar dicha unidad.

Nos leemos