如何通过纯GDI颜色混合(通过指定的alpha值着色)画布区域? [英] How to color blend (colorize by specified alpha value) the canvas area using pure GDI?

查看:360
本文介绍了如何通过纯GDI颜色混合(通过指定的alpha值着色)画布区域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用纯到表单的左上角如上所示:

 使用
PNGImage;

procedure TForm1.Button1Click(Sender:TObject);
var
图片:TPNGImage;
begin
图片:= 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;
结束
结束

有没有更有效的方法来使用纯GDI或Delphi VCL?

解决方案

您是否尝试过AlphaBlend的画布?





  Canvas.Draw(Arect.Left,ARect.Top,ABitmap,AAlphaBlendValue); 

与混合颜色的FillRect相结合



更新:这里有一些代码,尽可能靠近你的界面,但是纯VCL。

可能不是那么高效,但更简单(有点便携)。

如Remy所说,要以伪持久的方式在Form上绘制,您必须使用OnPaint ...

 程序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,0,bmp.Width,bmp.Height));
ACanvas.Draw(ARect.Left,ARect.Top,bmp,ABlendValue);
finally
bmp.Free;
结束
结束

procedure TForm1.Button1Click(Sender:TObject);
var
图片:TPNGImage;
begin
图片:= TPNGImage.Create;
try
Image.LoadFromFile('d:\6G3Eg.png');
ColorBlend(Image.Canvas,Image.Canvas.ClipRect,$ 0000FF80,175);
Canvas.Draw(0,0,Image);
//然后为乐趣做到它本身
ColorBlend(Canvas,ClientRect,clYellow,15);
finally
Image.Free;
结束
结束


I'd like to color blend (colorize by specified alpha value) the area of a canvas using pure Windows GDI (so without GDI+, DirectX or similar, no OpenGL, no assembler or a 3rd party libraries).

I've created the following function and I'd like to know if there is a more efficient or easier way to do this:

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;

For the notion of what this function should do see the following (discriminating :-) images:

And the code that can render this image to the top left side of the form in the way shown above:

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;

Is there a more efficient way to do this using pure GDI or Delphi VCL ?

解决方案

Have you tried the Canvas Drawing with AlphaBlend?

something like

Canvas.Draw(Arect.Left, ARect.Top, ABitmap, AAlphaBlendValue);

combined with a FillRect for the blend color

Update: And here's some code, as close as possible to your interface, but pure VCL.
Might not be as efficient, but much simpler (and somewhat portable).
As Remy said, to paint on a Form in a pseudo persistent way, you'd have to use 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,0,bmp.Width, bmp.Height));
    ACanvas.Draw(ARect.Left, ARect.Top, 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.Canvas.ClipRect, $0000FF80, 175);
    Canvas.Draw(0, 0, Image);
    // then for fun do it to the Form itself
    ColorBlend(Canvas, ClientRect, clYellow, 15);
  finally
    Image.Free;
  end;
end;

这篇关于如何通过纯GDI颜色混合(通过指定的alpha值着色)画布区域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆