⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blendu.~pa

📁 alpha blending routines for delphi
💻 ~PA
字号:
unit BlendU;
{
   This program was created by Josh Code to help illustrate how alpha blending
   can be achieved using the scanline function.

}
interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, jpeg, ExtCtrls, Spin,math;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    ImgMain: TImage;
    ImgBackground: TImage;
    ImgMaskMap: TImage;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    SpinEdit1: TSpinEdit;
    SpinEdit2: TSpinEdit;
    Label4: TLabel;
    Label5: TLabel;
    procedure TileBackground;
    procedure DrawBlend;
    procedure FormCreate(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure SpinEdit2Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
   BlendedBitmap: tbitmap;

implementation

{$R *.DFM}

procedure tform1.TileBackground;
var
  x,y: integer;
  // x,y -coordinates in height's and width's of the background
  h,w: integer; // the width and height of the background image being tiled
begin
     h:=imgBackground.height;
     w:=imgBackground.Width;
     for x:=0 to 5 do
         for y:=0 to 5 do
             BlendedBitmap.canvas.draw(x*w,y*h,imgBackground.picture.bitmap);
           // draw the background in different locations
end;

procedure tform1.DrawBlend;
var
  maskpba: pbytearray; // pointer to information in the mask bitmap
  Blendpba: pbytearray; // pointer to information in blendedbitmap
  Mainpba: pbytearray; // pointer to information in the main image being averaged with the background
  mx,my: integer; // used to draw the blend in an area that won't try accessing information outside the images
  x,y: integer; // coordinates of a pixel
  x2: integer; // used to hold x shl 2
  x3: integer; // used to hold x2 + left for the memory location in the
  left,top: integer; // the left and top positions of the blended graphic

begin
     TileBackGround; // clear blendedbitmap and tile the background image
     Left:=SpinEdit1.Value;
     top:=SpinEdit2.Value;
     // get the input coordinates
     mx:=Min(Min(BlendedBitmap.width-left,imgMaskMap.width),imgMain.width);
     // get the smallest width of an image
     my:=Min(Min(BlendedBitmap.Height-top,imgMaskMap.Height),imgMain.Height);
     // get the smallest Height of an image
     dec(mx); // subtract 1
     dec(my); // subtract 1
     left:=left shl 2; // now, instead of a # pixels from pixel 0, it is the number of bytes into the pointer
     // it is better to do this here than in the loop
     for y:=my downto 0 do // loop through the rows of pixels
     begin
          maskpba:=imgMaskMap.Picture.Bitmap.ScanLine[y];
          Blendpba:=BlendedBitmap.ScanLine[y+top];
          Mainpba:=imgMain.Picture.Bitmap.ScanLine[y];
          // get the pointers to rows of pixels data
          for x:=mx downto 0 do // loop through the various pixels in a row
          begin
               x2:=x shl 2;
               x3:=x2+left;
               // calculate the number of bytes into the pointer to the memory location of the pixel

               // average the 2 colours together by a ratio determined by the Mask
               // each part of the colour(red, green, and blue) is averaged separately
               Blendpba[x3]:=(Mainpba[x2]*Maskpba[x2]+Blendpba[x3]*($FF-Maskpba[x2])) shr 8;
               // average blue bytes
               inc(x2);
               inc(x3);
               Blendpba[x3]:=(Mainpba[x2]*Maskpba[x2]+Blendpba[x3]*($FF-Maskpba[x2])) shr 8;
               // average green bytes
               inc(x2);
               inc(x3);
               Blendpba[x2+left]:=(Mainpba[x2]*Maskpba[x2]+Blendpba[x3]*($FF-Maskpba[x2])) shr 8;
               // average red bytes
          end;
     end;
     canvas.draw(panel1.width,0,blendedBitmap);
     // draw the bitmap on the form
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
     BlendedBitmap:=tbitmap.create;
     imgMain.picture.bitmap.pixelformat:=pf32bit;
     imgMaskMap.picture.bitmap.pixelformat:=pf32bit;
     // pixelformat must be 32bit to work with the code, the way it is
     // If the drawalph code was changed, 24bit could also be used.
     // The pixelformat is importent when calculating the memory location of a pixel.
     // using scanline gives you a pointer to a row of pixels whereas
     // Using 32bit or 24bit causes each part of the colour to be separated into different bytes.
     // Using a format like 16bit, however, is more complex.
end;

procedure TForm1.FormResize(Sender: TObject);
begin
     BlendedBitmap.Height:=clientheight;
     if panel1.width<clientwidth then
        BlendedBitmap.Width:=clientwidth-panel1.Width;
     BlendedBitmap.pixelformat:=pf32bit;
     DrawBlend;
     Canvas.Draw(panel1.width,0,BlendedBitmap);
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
     Canvas.Draw(panel1.width,0,BlendedBitmap);
end;

procedure TForm1.SpinEdit2Change(Sender: TObject);
begin  // also linked to spinedit1
     drawblend;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -