Delphi   发布时间:2022-04-11  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了delphi – Alphablend和TransparentBlt大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
这个问题与我关于SO的 earlier question有关.

我想结合两个alpha层,只应用于源层的特定部分.我试过的一种方法是将sourceConstantAlpha设置为$ff(并让函数使用源图层中的alpha通道).

这种作品 – 尽管速度很慢(我想我可以通过使用ScanLines来加快速度),但这部分是因为我无法弄清楚将alpha通道设置为什么.文档表明计算是:

st.Red  = Src.Red   + (1 - Src.Alpha) * Dst.Red

我通过猜测工作尝试了一些不同的值,但我的第一个问题是:我如何计算alpha值?

在阅读了其他几个SO问题后,我遇到了TransparentBlt函数,它可以很好地屏蔽(和快速)但不透明,有没有办法结合
这两个一起调用(可能使用第三层)?

unit MainWnd;

interface

uses
  Windows,messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,ExtCtrls,ControlsEx;

type
{------------------------------------------------------------------------------}
  TfrmMain = class(TForm)
    PaintBox1: TPaintBox;
    procedure PaintBox1Paint(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

{..............................................................................}
procedure copyToAlpha(const in_bitmap : TBitmap; const in_transparentColor : TColor;
        const in_transparency : Integer);
var
  x : Integer;
  y : Integer;
  p : Integer;
begin
  ASSERT(in_bitmap.pixelFormat = pf32bit);

  for x := 0 to in_bitmap.Width - 1 do
  begin
    for y := 0 to in_bitmap.Height - 1 do
    begin
      p := in_bitmap.Canvas.Pixels[x,y];
      if TColor(p) <> in_transparentColor then
      begin
        in_bitmap.Canvas.Pixels[x,y] := p or (in_transparency shl 24);
      end
      else
        in_bitmap.Canvas.Pixels[x,y] := p or ($ff shl 24);
    end;
  end;  
end;

{..............................................................................}
procedure alphaBlendTest(
        const in_target : TCanvas;
        const in_width : Integer;
        const in_height : Integer);
const
  BARSIZE = 30;
var
  bitmap  : TBitmap;
  r       : TRect;
  blendFn : BLENDFUNCTION;
  ret     : Boolean;
begin
  blendFn.blendop             := AC_SRC_OVER;
  blendFn.sourceConstantAlpha := $ff;
  blendFn.blendFlags          := 0;
  blendFn.alphaFormat         := AC_SRC_ALPHA;

  bitmap := TBitmap.Create;
  try
    bitmap.Width              := in_width;
    bitmap.Height             := in_height;
    bitmap.pixelFormat        := pf32bit;
    bitmap.HandleType         := bmDIB;
    bitmap.TransparentColor   := clFuchsia;
    bitmap.Transparent        := true;  
    bitmap.Canvas.brush.Color := clFuchsia;
    bitmap.Canvas.FillRect(Bounds(0,in_width,in_height));
    bitmap.Canvas.brush.Color := clGreen;

    r := Bounds(
        in_width div 2 - (in_width div 3) div 2,(in_width div 3) + 1,BARSIZE          + 1);

   bitmap.Canvas.Rectangle(r);
   // done drawing

   //copyToAlpha(bitmap,clFuchsia,1);
   ret := Windows.TransparentBlt(
        in_target.Handle,in_height,bitmap.Canvas.Handle,clFuchsia);
        //blendFn);

    ASSERT(ret);
  finally
    bitmap.Free;
  end;
end;



{..............................................................................}
procedure TfrmMain.PaintBox1Paint(Sender: TObject);
var
  r: TRect;
begin
  PaintBox1.Canvas.brush.Color := clBlue;
  r := Bounds(0,PaintBox1.ClientWidth,PaintBox1.ClientHeight);
  PaintBox1.Canvas.FillRect(r);
  PaintBox1.Canvas.brush.Color := clRed;
  PaintBox1.Canvas.Ellipse(0,PaintBox1.ClientHeight);

  alphaBlendTest(PaintBox1.Canvas,PaintBox1.ClientHeight);
end;

end.

解决方法

技巧:以任何比例混合相同的颜色会产生相同的颜色.

因此,最简单的方法(也许也是最有效的方法)是首先将透明结果绘制到临时位图,然后在目标画布上绘制位图的alphablend.

在绘图期间访问目标画布:

procedure TfrmMain.PaintBox1Paint(Sender: TObject);
const
  BarSize = 30;
var
  R: TRect;
  Bmp: TBitmap;
  BlendFunc: TBlendFunction;
begin
  with PaintBox1 do
  begin
    R := ClientRect;
    Canvas.brush.Color := clBlue;
    Canvas.FillRect(R);
    Canvas.brush.Color := clRed;
    Canvas.Ellipse(R);
    Bmp := TBitmap.Create;
    try
      Bmp.Width := Width;
      Bmp.Height := Height;
      BitBlt(Bmp.Canvas.Handle,Width,Height,Canvas.Handle,SRCCOPY);
      Bmp.Canvas.brush.Color := clGreen;
      R := Bounds(Width div 3,Width div 3 + 1,BarSize + 1);
      Bmp.Canvas.Rectangle(R);
      BlendFunc.blendop := AC_SRC_OVER;
      BlendFunc.blendFlags := 0;
      BlendFunc.sourceConstantAlpha := 80;
      BlendFunc.AlphaFormat := 0;
      Windows.AlphaBlend(Canvas.Handle,Bmp.Canvas.Handle,BlendFunc);
    finally
      Bmp.Free;
    end;
  end;
end;

并且在绘图期间无法访问目标画布:

procedure GetRemoteBitmap(Bmp: TBitmap; Width,Height: Integer);
const
  BarSize = 30;
var
  R: TRect;
begin
  Bmp.Canvas.brush.Color := clFuchsia;
  Bmp.Width := Width;
  Bmp.Height := Height;
  Bmp.TransparentColor := clFuchsia;
  Bmp.Transparent := True;
  Bmp.Canvas.brush.Color := clGreen;
  R := Bounds(Width div 3,BarSize + 1);
  Bmp.Canvas.Rectangle(R);
end;

procedure TfrmMain.PaintBox1Paint(Sender: TObject);
var
  R: TRect;
  Bmp: TBitmap;
  Tmp: TBitmap;
  BlendFunc: TBlendFunction;
begin
  with PaintBox1 do
  begin
    R := ClientRect;
    Canvas.brush.Color := clBlue;
    Canvas.FillRect(R);
    Canvas.brush.Color := clRed;
    Canvas.Ellipse(R);
    Bmp := TBitmap.Create;
    Tmp := TBitmap.Create;
    try
      GetRemoteBitmap(Bmp,Height);
      Tmp.Width := Width;
      Tmp.Height := Height;
      BitBlt(Tmp.Canvas.Handle,SRCCOPY);
      TransparentBlt(Tmp.Canvas.Handle,ColorToRGB(clFuchsia));
      BlendFunc.blendop := AC_SRC_OVER;
      BlendFunc.blendFlags := 0;
      BlendFunc.sourceConstantAlpha := 80;
      BlendFunc.AlphaFormat := 0;
      Windows.AlphaBlend(Canvas.Handle,Tmp.Canvas.Handle,BlendFunc);
    finally
      Tmp.Free;
      Bmp.Free;
    end;
  end;
end;

大佬总结

以上是大佬教程为你收集整理的delphi – Alphablend和TransparentBlt全部内容,希望文章能够帮你解决delphi – Alphablend和TransparentBlt所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:delphi