我希望您能使用纯
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, 0, ARect.Right - ARect.Left,
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.Right - ARect.Left, ARect.Bottom - ARect.Top, DC, 0, 0,
ARect.Right - ARect.Left, ARect.Bottom - ARect.Top, 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, 0, Image);
finally
Image.Free;
end;
end;
有没有使用纯GDI或Delphi VCL更高效的方法来完成这个任务?
AlphaBlend()
是实现这一功能的简单方法 - 让操作系统来完成工作。否则,您将不得不直接操作PNG像素。您可以进一步进行的唯一优化是创建一次固定位图并反复重用它。 - Remy Lebeau现有画布
区域上色,与PNG无关。那是个糟糕的例子,我知道。也许您可以以一种没有更多改进的方式发布答案,那样我会很高兴的 :-) - TLama