我想使用纯
Windows GDI(不使用GDI,DirectX或类似,没有OpenGL,没有汇编程序或第三方库)对画布区域进行颜色混合(使用指定的alpha值着色).
我已经创建了以下函数,我想知道是否有更高效或更简单的方法来执行此操作:
procedure ColorBlend(const ACanvas: HDC; const ARect: TRect;
const ABlendColor: TColor; const ABlendValue: Integer);
var
DC: HDC;
Brush: HBrush;
Bitmap: HBITMAP;
BlendFunction: TBlendFunction;
begin
DC := CreateCompatibleDC(ACanvas);
Bitmap := CreateCompatibleBitmap(ACanvas,ARect.Right - ARect.Left,ARect.Bottom - ARect.Top);
Brush := CreateSolidBrush(ColorToRGB(ABlendColor));
try
SelectObject(DC,Bitmap);
Windows.FillRect(DC,Rect(0,ARect.Bottom - ARect.Top),Brush);
BlendFunction.BlendOp := AC_SRC_OVER;
BlendFunction.BlendFlags := 0;
BlendFunction.AlphaFormat := 0;
BlendFunction.sourceConstantAlpha := ABlendValue;
Windows.AlphaBlend(ACanvas,ARect.Left,ARect.Top,ARect.Bottom - ARect.Top,DC,BlendFunction);
finally
DeleteObject(Brush);
DeleteObject(Bitmap);
DeleteDC(DC);
end;
end;
有关此功能应该做什么的概念,请参阅以下内容(区分:-)图像:
并且代码可以通过上面显示的方式将this image呈现到表单的左上方:
uses
PNGImage;
procedure TForm1.Button1Click(Sender: TObject);
var
Image: TPNGImage;
begin
Image := TPNGImage.Create;
try
Image.LoadFromFile('d:\6G3Eg.png');
ColorBlend(Image.Canvas.Handle,Image.Canvas.ClipRect,$0000FF80,175);
Canvas.Draw(0,Image);
finally
Image.Free;
end;
end;
使用纯GDI或Delphi VCL有更有效的方法吗?
解决方法
你是否尝试过AlphaBlend的Canvas绘图?
就像是
Canvas.Draw(Arect.Left,ABitmap,AAlphaBlendValue);
结合FillRect的混合颜色
更新:这里有一些代码,尽可能接近您的界面,但纯VCL.
可能不那么高效,但更简单(并且有点便携).
正如Remy所说,要以伪持久的方式在Form上绘制,你必须使用OnPaint ……
procedure ColorBlend(const ACanvas: TCanvas; const ARect: TRect;
const ABlendColor: TColor; const ABlendValue: Integer);
var
bmp: TBitmap;
begin
bmp := TBitmap.Create;
try
bmp.Canvas.Brush.Color := ABlendColor;
bmp.Width := ARect.Right - ARect.Left;
bmp.Height := ARect.Bottom - ARect.Top;
bmp.Canvas.FillRect(Rect(0,bmp.Width,bmp.Height));
ACanvas.Draw(ARect.Left,bmp,ABlendValue);
finally
bmp.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Image: TPNGImage;
begin
Image := TPNGImage.Create;
try
Image.LoadFromFile('d:\6G3Eg.png');
ColorBlend(Image.Canvas,Image);
// then for fun do it to the Form itself
ColorBlend(Canvas,ClientRect,clYellow,15);
finally
Image.Free;
end;
end;