📄 blendu.~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 + -