BGRABitmap tutorial 5/es

From Lazarus wiki
Jump to navigationJump to search

Deutsch (de) English (en) español (es) français (fr)


Home | Tutorial 1 | Tutorial 2 | Tutorial 3 | Tutorial 4 | Tutorial 5 | Tutorial 6 | Tutorial 7 | Tutorial 8 | Tutorial 9 | Tutorial 10 | Tutorial 11 | Tutorial 12 | Edit

Esta tutoría muestra como usar capas.

Crear un nuevo proyecto

Crea un nuevo proyecto y añade referencia a BGRABitmap, de la misma forma que en la primer tutoría.

Acerca de las máscaras

Una máscara es una imágen de escala de grises. Cuando una máscara es aplicada en una imágen, las partes de la imágen que coinciden con las partes negras de la máscara son borradas y se convierten en transparentes, considerando que las partes que se superponen con las partes blancas de la máscara se mantienen. En otras palabras, la máscara es como un canal alfa define la opacidad. Si el valor de la máscara es cero, entonces se convierte en transparente, y si el valor de la máscara es de 255, se vuelve opaco.

BGRATutorial5d.png

En este ejemplo, en la imágen, la imagen de inicio está en la esquina superior izquierda, la máscara en la parte superior derecha, y el resultado al aplicar la máscara en la esquina inferior izquierda. Código en OnPaint :

var temp,tex,mask: TBGRABitmap;
begin
  temp:= TBGRABitmap.Create(640,480,ColorToBGRA(ColorToRGB(clBtnFace)));

  //cargando y escalando la textura
  tex := TBGRABitmap.Create('texture.png');
  BGRAReplace(tex,tex.Resample(128,80));

  //muestra una imágen en la esquina superior izquierda
  temp.PutImage(10,10,tex,dmDrawWithTransparency);

  //crea una máscara con un elipse y un rectángulo
  mask := TBGRABitmap.Create(128,80,BGRABlack);
  mask.FillEllipseAntialias(40,40,30,30,BGRAWhite);
  mask.FillRectAntialias(60,40,100,70,BGRAWhite);

  //muestra la máscara en la parte superior derecha
  temp.PutImage(150,10,mask,dmDrawWithTransparency);

  //aplica la máscara a la imágen
  tex.ApplyMask(mask);

  //muestra la imágen resultante en la esquina inferior izquierda
  temp.PutImage(10,100,tex,dmDrawWithTransparency);

  mask.Free;
  tex.Free;

  //muestra todo en la pantalla
  image.Draw(Canvas,0,0,True);
  image.Free;
end;

Borrando las partes de una imágen

Algunas funciones permiten borrar una elipse, un rectángulo, etc. Esto significa que la parte de la imagen se vuelve transparente. Por tanto, es posible establecer un agujero en una imagen. Si el parámetro alfa es de 255, el agujero es completamente transparente. Sino, el agujero es semitransparente.

BGRATutorial5e.png

Aquí una elipse se borra de la izquierda con un parámetro alfa de 255, y otra elipse se borra a la derecha con un parámetro alfa del 128. Código OnPaint :

var image,tex: TBGRABitmap;
begin
  image := TBGRABitmap.Create(640,480,ColorToBGRA(ColorToRGB(clBtnFace)));

  //muestra y escala la textura
  tex := TBGRABitmap.Create('texture.png');
  BGRAReplace(tex,tex.Resample(128,80));

  //muestra la imágen
  image.PutImage(10,10,tex,dmDrawWithTransparency);

  //borra las partes
  tex.EraseEllipseAntialias(40,40,30,30,255);
  tex.EraseEllipseAntialias(80,40,30,30,128);

  //muestra el resultado
  image.PutImage(10,100,tex,dmDrawWithTransparency);

  tex.Free;

  //muestra todo en la pantalla
  image.Draw(Canvas,0,0,True);
  image.Free;
end;

Agrega un manejador de pintado

Con el inspector de objetos, agrega un manejador OnPaint y escribe :

procedure TForm1.FormPaint(Sender: TObject);
var image: TBGRABitmap;
    size: single;

  procedure DrawMoon;
  var layer: TBGRABitmap;
  begin
    layer := TBGRABitmap.Create(image.Width,image.Height);
    layer.FillEllipseAntialias(layer.Width/2,layer.Height/2,size*0.4,size*0.4,BGRA(224,224,224,128));
    layer.EraseEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.3,size*0.3,255);
    image.PutImage(0,0,layer,dmDrawWithTransparency);
    layer.Free;
  end;

begin
  image := TBGRABitmap.Create(ClientWidth,ClientHeight);

  //Computa el espacio disponible en ambas direcciones
  if image.Height < image.Width then
    size := image.Height
  else
    size := image.Width;

  image.GradientFill(0,0,image.Width,image.Height,
                     BGRA(128,192,255),BGRA(0,0,255),
                     gtLinear,PointF(0,0),PointF(0,image.Height),
                     dmSet);

  DrawMoon;

  image.Draw(Canvas,0,0,True);
  image.free;
end;

El procedimiento crea una imágen y la rellena con un degradado azúl. Esta es la capa de fondo.

El procedimiento DrawMoon crea una capa, dibuja una luna en el mismo. En primer lugar un disco blanco se dibuja, a continuación, un disco más pequeño se resta. Por último, esta capa se fusiona con el fondo.

Ejecuta el programa

Deberías ver un cielo azúl con una luna. Cuando cambia el tamaño de la forma, la imagen cambia de tamaño en consecuencia.

Tutorial5a.png

Añade otra capa con un sol

En el evento OnPaint, añade el siguiente subprocedimiento :

  procedure DrawSun;
  var layer,mask: TBGRABitmap;
  begin
    layer := TBGRABitmap.Create(image.Width,image.Height);
    layer.GradientFill(0,0,layer.Width,layer.Height,
                       BGRA(255,255,0),BGRA(255,0,0),
                       gtRadial,PointF(layer.Width/2,layer.Height/2-size*0.15),PointF(layer.Width/2+size*0.45,layer.Height/2-size*0.15),
                       dmSet);
    mask := TBGRABitmap.Create(layer.Width,layer.Height,BGRABlack);
    mask.FillEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.25,size*0.25,BGRAWhite);
    layer.ApplyMask(mask);
    mask.Free;
    image.PutImage(0,0,layer,dmDrawWithTransparency);
    layer.Free;
  end;

Este procedimiento crea un gradiente radial de color rojo y naranja y se aplica una máscara circular a la misma. Esto da como resultado un disco de color. Por último, la capa se fusiona con el fondo.

Agregue una llamada a este procedimiento para dibujarlo después de la luna.

Ejecuta el programa

Deberías ver un cielo azúl con una luna y un sol. Cuando cambia el tamaño de la forma, la imagen cambia de tamaño en consecuencia.

BGRATutorial5b.png

Añade una capa de luz

Añade el siguiente subprocedimiento en el evento OnPaint :

  procedure ApplyLight;
  var layer: TBGRABitmap;
  begin
    layer := TBGRABitmap.Create(image.Width,image.Height);
    layer.GradientFill(0,0,layer.Width,layer.Height,
                       BGRA(255,255,255),BGRA(64,64,64),
                       gtRadial,PointF(layer.Width*5/6,layer.Height/2),PointF(layer.Width*1/3,layer.Height/4),
                       dmSet);
    image.BlendImage(0,0,layer,boMultiply);
    layer.Free;
  end;

Este procedimiento dibuja una capa con un degradado radial blanco. Luego es aplicado para multiplicar la imágen.

Código resultante

procedure TForm1.FormPaint(Sender: TObject);
var image: TBGRABitmap;
    size: single;

  procedure DrawMoon;
  var layer: TBGRABitmap;
  begin
    layer := TBGRABitmap.Create(image.Width,image.Height);
    layer.FillEllipseAntialias(layer.Width/2,layer.Height/2,size*0.4,size*0.4,BGRA(224,224,224,128));
    layer.EraseEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.3,size*0.3,255);
    image.PutImage(0,0,layer,dmDrawWithTransparency);
    layer.Free;
  end;

  procedure DrawSun;
  var layer,mask: TBGRABitmap;
  begin
    layer := TBGRABitmap.Create(image.Width,image.Height);
    layer.GradientFill(0,0,layer.Width,layer.Height,
                       BGRA(255,255,0),BGRA(255,0,0),
                       gtRadial,PointF(layer.Width/2,layer.Height/2-size*0.15),PointF(layer.Width/2+size*0.45,layer.Height/2-size*0.15),
                       dmSet);
    mask := TBGRABitmap.Create(layer.Width,layer.Height,BGRABlack);
    mask.FillEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.25,size*0.25,BGRAWhite);
    layer.ApplyMask(mask);
    mask.Free;
    image.PutImage(0,0,layer,dmDrawWithTransparency);
    layer.Free;
  end;

  procedure ApplyLight;
  var layer: TBGRABitmap;
  begin
    layer := TBGRABitmap.Create(image.Width,image.Height);
    layer.GradientFill(0,0,layer.Width,layer.Height,
                       BGRA(255,255,255),BGRA(64,64,64),
                       gtRadial,PointF(layer.Width*5/6,layer.Height/2),PointF(layer.Width*1/3,layer.Height/4),
                       dmSet);
    image.BlendImage(0,0,layer,boMultiply);
    layer.Free;
  end;

begin
  image := TBGRABitmap.Create(ClientWidth,ClientHeight);

  if image.Height < image.Width then
    size := image.Height
  else
    size := image.Width;

  image.GradientFill(0,0,image.Width,image.Height,
                     BGRA(128,192,255),BGRA(0,0,255),
                     gtLinear,PointF(0,0),PointF(0,image.Height),
                     dmSet);

  DrawMoon;
  DrawSun;
  ApplyLight;

  image.Draw(Canvas,0,0,True);
  image.free;
end;

Ejecuta el programa

Deberías ver un cielo azúl con una luna y un sol, con un efecto de iluminación. Cuando cambia el tamaño de la forma, la imagen cambia de tamaño en consecuencia.

Tutorial5c.png

Tutoría anterior (acceso directo a píxeles) | Siguiente tutoría (estilo de línea)