function RedComponent(Color32: TColor32): Integer;
function GreenComponent(Color32: TColor32): Integer;
function BlueComponent(Color32: TColor32): Integer;
function AlphaComponent(Color32: TColor32): Integer;
function Intensity(Color32: TColor32): Integer;
function RGBA(R, G, B: Byte; A: Byte = $FF): TColor32;
function RGBAToColor32(RGBA: TRGBQuad): TColor32;
function Color32ToRGBA(Color32: TColor32): TRGBQuad;
{ An analogue of FillChar for 32 bit values }
procedure FillLongword(var X; Count: Integer; Value: Longword);
for y := Tr.Top to Tr.Bottom - 1 do
begin
Target := Tge.ScanLine[y];
Source := ScanLine[y - Dsty];
for x := Tr.Left to Tr.Right - 1 do
begin
//这里替换了
// CombineAlphaPixel(Target^[x], Target^[x], Target^[x].rgbReserved, Source^[x - DstX], Source^[x- DstX].rgbReserved);
AlphaBlendPixel(Target^[x], Source^[x]);
end;
end;
end;
for i := 0 to LayerList.Count -1 do
begin
TBitmap32(LayerList.Items[i ]).DrawTo(0,0, Image1.Picture.Bitmap);
end;
}
//o:o:o:o:o//
for y := Tr.Top to Tr.Bottom - 1 do
begin
Source := Src.ScanLine[y - Dsty];
Target := ScanLine[y];
for x := TR.Left to Tr.Right - 1 do
begin
CombineAlphaPixel(Target^[x], Target^[x], Target^[x].rgbReserved, Source^[x - DstX], Source^[x- DstX].rgbReserved);
// AlphaBlendPixel(Target^[x], Source^[x]);
end;
end;
end;
procedure TBitmap32.DrawTo(DstX, DstY: Integer; Tge: TBitmap32);
var
x, y: integer;
TR, SR: TRect;
Source, Target: pRGBQuadArray;
begin
for y := Tr.Top to Tr.Bottom - 1 do
begin
Target := Tge.ScanLine[y];
Source := ScanLine[y - Dsty];
for x := TR.Left to Tr.Right - 1 do
begin
CombineAlphaPixel(Target^[x], Target^[x], Target^[x].rgbReserved, Source^[x - DstX], Source^[x- DstX].rgbReserved);
// AlphaBlendPixel(Target^[x], Source^[x]);
end;
end;
for y := Tr.Top to Tr.Bottom - 1 do
begin
Target := Tge.ScanLine[y];
Source := ScanLine[y - Dsty];
for x := Tr.Left to Tr.Right - 1 do
begin
// CombineAlphaPixel(Target^[x], Target^[x], Target^[x].rgbReserved, Source^[x - DstX], Source^[x- DstX].rgbReserved);
AlphaBlendPixel(Target^[x], Source^[x]);
end;
end;
end;
procedure TBitmap32.Clear(color: TColor32);
var
x, y: integer;
begin
FillLongword(GetBits^[0], Width * Height, Color);
end;
procedure TBitmap32.FillRect(X1, Y1, X2, Y2: Integer; Value: TColor32);
var
j: Integer;
P: PColor32Array;
begin
for j := Y1 to Y2 - 1 do
begin
P := Pointer(ScanLine[j]);
FillLongword(P[X1], X2 - X1, Value);
end;
end;
procedure TBitmap32.Clear(Bitmap: TBitmap; color: TColor32);
var
bits: PColor32Array;
begin
Bitmap.PixelFormat := pf32bit;
bits := Bitmap.ScanLine[Bitmap.Height - 1];
FillLongword(Bits^[0], Width * Height, Color);
end;
procedure TBitmap32.Clear;
begin
Clear(clBlack32);
end;
procedure TBitmap32.SetAlphaChannels(Alpha: BYTE);
var
x, y: integer;
SS: pRGBQuadArray;
begin
for y := 0 to Height-1 do
begin
SS := ScanLine[y];
for x := 0 to Width-1 do
begin
SS^[x].rgbReserved := Alpha;
end;
end;
end;
{
procedure TBitmap32.SetAlphaChannels(Bitmap: TBitmap);
var
x, y: integer;
DS: pRGBQuadArray;
SS: pByteArray;
begin
for y := 0 to Height-1 do
begin
DS := ScanLine[y];
SS := Bitmap.ScanLine[y];
for x := 0 to Width-1 do
begin
DS^[x].rgbReserved := SS^[x];
end;
end;
end;
}
procedure TBitmap32.SetAlphaChannels(Mask8: TBitmap);
var
x, y: integer;
DS: pRGBQuadArray;
SS: pByteArray;
Bits1: pRGBQuadArray;
Bits2: pByteArray;
begin
{ Bits1 := ScanLine[Height-1];
Bits2 := Bitmap.ScanLine[Bitmap.height-1];
for x := 0 to Width * Height-1 do
begin
Bits1^[x].rgbReserved := 1;
end;
}
for y := 0 to Height-1 do
begin
DS := ScanLine[y];
SS := Mask8.ScanLine[y];
for x := 0 to Width-1 do
begin
DS^[x].rgbReserved := SS^[x];
end;
end;
end;
procedure TBitmap32.SetAlphaChannels(Bitmap: TBitmap; Alpha: Byte);
var
x, y: integer;
SS: pRGBQuadArray;
begin
for y := 0 to Bitmap.Height-1 do
begin
SS := Bitmap.ScanLine[Bitmap.Height - y -1];
for x := 0 to Bitmap.Width-1 do
begin
SS^[x].rgbReserved := Alpha;
end;
end;
end;
procedure TBitmap32.SetPixel(x, y: integer; color: TColor32);
begin
if (X >= 0) and (X < Width) and (Y >= 0) and (Y < Height) then
GetBits^[x + (Height - y -1) * Width] := color;
end;
function TBitmap32.GetPixel(x, y: integer): TColor32;
begin
Result := $00000000;
if (X >= 0) and (X < Width) and (Y >= 0) and (Y < Height) then
Result := GetBits^[x + (Height - y -1) * Width];
end;
procedure TBitmap32.Assign(Source: TPersistent);
begin
inherited Assign(Source);
PixelFormat := pf32bit;
end;
procedure TBitmap32.AlphaBlendPixel(var pDest: TRGBQuad; pSrc: TRGBQuad);
begin
if (pSrc.rgbReserved = $FF) then
begin
PRGBArray(pDest) := PRGBArray(pSrc);
exit;
end;
if (pSrc.rgbReserved = 0) then
exit;
// 以下用不着判断[0,0xFF],我验算过了
if (PRGBArray(pSrc) <> PRGBArray(pDest)) then
begin
pDest.rgbBlue := (PSrc.rgbBlue - pDest.rgbBlue) * pSrc.rgbReserved div $FF + pDest.rgbBlue;
pDest.rgbGreen := (PSrc.rgbGreen - pDest.rgbGreen) * pSrc.rgbReserved div $FF + pDest.rgbGreen;
pDest.rgbRed := (PSrc.rgbRed - pDest.rgbRed) * pSrc.rgbReserved div $FF + pDest.rgbRed;
end;
end;
procedure StrectchDrawGraphic(ACanvas: TCanvas; ARect: TRect; AGraphic: TGraphic;
BkColor: TColor);
var
Bmp: TBitmap;
begin
if AGraphic is TIcon then
begin
// TIcon 不支持缩放绘制,通过 TBitmap 中转
Bmp := TBitmap.Create;
try
Bmp.Canvas.Brush.Color := BkColor;
Bmp.Canvas.Brush.Style := bsSolid;
Bmp.Width := AGraphic.Width;
Bmp.Height := AGraphic.Height;
//Bmp.Canvas.FillRect(Rect(0, 0, Bmp.Width, Bmp.Height));
Bmp.Canvas.Draw(0, 0, AGraphic);
ACanvas.StretchDraw(ARect, Bmp);
finally
Bmp.Free;
end;
end
else
ACanvas.StretchDraw(ARect, AGraphic);
end;
//绘制平铺图
procedure TBitmap32.DrawTiled(Canvas: TCanvas; Rect: TRect; G: TGraphic);
var
R, Rows, C, Cols: Integer;
begin
if (G <> nil) and (not G.Empty) then
begin
Rows := ((Rect.Bottom - Rect.Top) div G.Height) + 1;
Cols := ((Rect.Right - Rect.Left) div G.Width) + 1;
for R := 1 to Rows do
for C := 1 to Cols do
Canvas.Draw(Rect.Left + (C - 1) * G.Width, Rect.Top + (R - 1) * G.Height, G);
end;
end;
//创建纹理图
procedure TBitmap32.CreateForeBmp(Mode: TTextureMode; G: TGraphic; BkColor: TColor);
begin
//创建渐变色前景
procedure TBitmap32.CreateGradual(Style: TGradualStyle; StartColor, EndColor: TColor);
var
Buf, Dst: PRGBArray;
BufLen, Len: Integer;
SCol, ECol: TColor;
sr, sb, sg: Byte;
er, eb, eg: Byte;
BufSize: Integer;
i, j: Integer;
begin
PixelFormat := pf24bit;
if Style in [gsLeftToRight, gsRightToLeft, gsCenterToLR] then
BufLen := Width // 缓冲区长度
else
BufLen := Height;
if Style in [gsCenterToLR, gsCenterToTB] then
Len := (BufLen + 1) div 2 // 渐变带长度
else
Len := BufLen;
BufSize := BufLen * 3;
GetMem(Buf, BufSize);
try
// 创建渐变色带缓冲区
if Style in [gsLeftToRight, gsTopToBottom] then
begin
SCol := ColorToRGB(StartColor);
ECol := ColorToRGB(EndColor);
end
else begin
SCol := ColorToRGB(EndColor);
ECol := ColorToRGB(StartColor);
end;
sr := GetRValue(SCol); //起始色
sg := GetGValue(SCol);
sb := GetBValue(SCol);
er := GetRValue(ECol); //结束色
eg := GetGValue(ECol);
eb := GetBValue(ECol);
for i := 0 to Len - 1 do
begin
Buf[i ].rgbtRed := sr + (er - sr) * i div Len;
Buf[i ].rgbtGreen := sg + (eg - sg) * i div Len;
Buf[i ].rgbtBlue := sb + (eb - sb) * i div Len;
end;
if Style in [gsCenterToLR, gsCenterToTB] then // 对称渐变
for i := 0 to Len - 1 do
Buf[BufLen - 1 - i] := Buf[i ];
if Style in [gsLeftToRight, gsRightToLeft, gsCenterToLR] then
for i := 0 to Height - 1 do // 水平渐变
Move(Buf[0], ScanLine[Height - i - 1]^, BufSize)
else
for i := 0 to Height - 1 do // 垂直渐变
begin
Dst := ScanLine[Height - i - 1];
for j := 0 to Width - 1 do
Dst^[j] := Buf[i ];
end;
finally
FreeMem(Buf);
end;
for y := Tr.Top to Tr.Bottom - 1 do
begin
Target := TargetBitmap.ScanLine[y];
Source := Mask8.ScanLine[y - Dsty];
for x := TR.Left to Tr.Right - 1 do
begin
if (Target^[x] + Source^[x - Dstx]) > 255 then
Target^[x] := 255
else
Target^[x] := Target^[x] + Source^[x - Dstx];
end;
end;
end;
//开始增量计算
for i := 0 to nInc -1 do
begin
nJudgeX := nJudgeX + nTwoIx;
nJudgeY := nJudgeY + nTwoIy;
//通过增量法计算的当前点是否属于直线上的点
bPlot := FALSE;
//检测 X 方向
if(nJudgeX >= 0) then
begin
bPlot := TRUE;
nJudgeX := nJudgeX - nTwoIy;
//将任意走向的直线统一起来
if(nDx > 0) then
inc(x)
else if(nDx < 0) then
dec(x)
end;
//检测 Y 方向
if(nJudgeY >= 0) then
begin
bPlot := TRUE;
nJudgeY := nJudgeY - nTwoIx;
//将任意走向的直线统一起来
if(nDy > 0) then
inc(y)
else if(nDy < 0) then
dec(y);
end;
//如果当前点在直线上, 则绘制当前点
if(bPlot) then
// SetPixel(hdc, x, y, clr);
DrawMaskPen(Target, x- MaskPen8.Width div 2, y- MaskPen8.Height div 2, MaskPen8);
end;//end for
end;
function CrossFadeColor(FromColor, ToColor: TColor32; Rate: Single) : TColor32;
var
R,G,B,A: BYTE;
begin
// r := Round(RedComponent(FromColor) * Rate + RedComponent(ToColor) * (1 - Rate));
// g := Round(GreenComponent(FromColor) * Rate + GreenComponent(ToColor) * (1 - Rate));
// b := Round(BlueComponent(FromColor) * Rate + BlueComponent(ToColor) * (1 - Rate));
// a := Round(AlphaComponent(FromColor) * Rate + AlphaComponent(ToColor) * (1 - Rate));
r := RedComponent(FromColor);
g := GreenComponent(FromColor);
b := BlueComponent(FromColor);
a := Round(AlphaComponent(FromColor) * Rate);
Result := RGBA(r,g,b,a); //RGB(b,g,r);
end;
// type
// intarray = array[0..1] of integer;
// pintarray = ^intarray;
procedure hpixel(x : single; y : integer);
var
FadeRate : single;
begin
FadeRate := x - trunc(x);
with bitmap do
begin
if (x>=0) and (y>=0) and (height>y) and (width>x) then
pColor32array(bitmap.ScanLine[y])[trunc(x)] := CrossFadeColor(Color,pColor32array(bitmap.ScanLine[y])[trunc(x)],1-FadeRate);
if (trunc(x)+1>=0) and (y>=0) and (height>y) and (width>trunc(x)+1) then
pColor32array(bitmap.ScanLine[y])[trunc(x)+1]:=CrossFadeColor(Color,pColor32array(bitmap.ScanLine[y])[trunc(x)+1],FadeRate);
end;
end;
procedure vpixel(x : integer; y : single);
var
FadeRate : single;
begin
FadeRate:=y-trunc(y);
with bitmap do
begin
if (x>=0) and (trunc(y)>=0) and (height>trunc(y)) and (width>x) then
pColor32array(bitmap.ScanLine[trunc(y)])[x]:=CrossFadeColor(Color,pColor32array(bitmap.ScanLine[trunc(y)])[x],1-FadeRate);
if (x>=0) and (trunc(y)+1>=0) and (height>trunc(y)+1) and (width>x) then
pColor32array(bitmap.ScanLine[trunc(y)+1])[x]:=CrossFadeColor(Color,pColor32array(bitmap.ScanLine[trunc(y)+1])[x],FadeRate);
end;
end;
var i: integer;
ly, lx, currentx, currenty, deltax, deltay, l, skipl: single;
begin
if (x1 <> x2) or (y1 <> y2) then
begin
// bitmap.PixelFormat := pf32Bit;
// Bitmap.Clear($00000000);
if lx > ly then
begin
l := trunc(lx);
deltay := (y2-y1)/l;
if x1 > x2 then
begin
deltax := -1;
skipl := (currentx - trunc(currentx));
end
else
begin
deltax := 1;
skipl := 1- (currentx - trunc(currentx));
end;
end
else
begin
l := trunc(ly);
deltax := (x2-x1)/l;
if y1 > y2 then
begin
deltay := -1;
skipl := (currenty-trunc(currenty));
end
else
begin
deltay := 1;
skipl := 1-(currenty-trunc(currenty));
end;
end;