如何在位图图像上使用纯VCL进行混合和透明?

时间:2014-05-16 19:06:26

标签: delphi gdi delphi-xe5 alphablending

this question类似,我希望同时混合颜色和位图(png或bmp,但在我的情况下,我使用的是png),同时保持透明度。

与链接问题一样,我希望(a)不使用第三方库,(b)尽可能使用VCL内置技术,但在需要时使用Win32 GDI API,以及(c)不使用GDI +

这个简单的代码,基于链接问题中的代码,我看到颜色混合有效但PNG文件的透明度不会保留,当我这样做时:

我尝试过的事情:   - 不同的像素格式(pf32bit,pf24bit)   - TBitmap.Transparent的不同值。

我在Delphi XE5和XE6中尝试了这种情况,在这种情况下,但我怀疑同样的事情对XE2起作用了。

演示代码:

unit BlendUnit2;


{ Investigating VCL alpha blending GDI capability }

interface

uses
   Winapi.Windows,
   Winapi.Messages,
   System.SysUtils,
   System.Variants,
   System.Classes,
   Vcl.Graphics,
   Vcl.Controls,
   Vcl.Forms,
   Vcl.Dialogs,
   Vcl.ExtCtrls,
   Vcl.Imaging.pngimage,
   Vcl.StdCtrls;

type
  TForm2 = class(TForm)
    BackgroundImage: TImage;
    TransparentImageInDFM: TImage;
    GeneratedImage: TImage;
    Label1: TLabel;
    Shape1: TShape;
    Shape2: TShape;
    Label2: TLabel;
    Label3: TLabel;
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  public
    { Public declarations }
    procedure Blend(ACanvas:TCanvas);
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure ColorBlend(const ACanvas: TCanvas; const ARect: TRect;
  const ABlendColor: TColor; const ABlendValue: Integer);
var
  bmp: TBitmap;
begin
  bmp := TBitmap.Create;
//  bmp.PixelFormat := pf32bit;
//  bmp.AlphaFormat := afPremultiplied;
//  bmp.Transparent  := True;
  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 TForm2.Blend(ACanvas:TCanvas);
var
  Image: TPNGImage;
begin
  Image := TPNGImage.Create;
  try
    Image.LoadFromFile('..\..\AppIcon2013.png');
    ColorBlend(Image.Canvas, Image.Canvas.ClipRect, $00CCFF80, 85);
    ACanvas.Draw(0, 0, Image);
  finally
    Image.Free;
  end;
end;


procedure TForm2.FormDestroy(Sender: TObject);
begin
//
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
//   GeneratedImage.Picture.Bitmap.Transparent := false;
//   GeneratedImage.Picture.Bitmap.PixelFormat := pf32bit;
   GeneratedImage.Picture.Bitmap.SetSize(280,280);

   Blend( GeneratedImage.Picture.Bitmap.Canvas );
end;

end.

屏幕截图显示右侧未混合但正确透明的图像,左侧是混合但不再透明的图像:

enter image description here

注意:我认为使用对AlphaBlend的Win32 API调用预先混合背景和前景可能是唯一的方法,在这种情况下,VCL不包含任何值得一提的内置透明度支持。 (StackOverflow上有人告诉我,他认为第三方图书馆是不值得的,因为这是内置于VCL中,我想知道他是否正确,所以我只想用VCL做这件事。)

0 个答案:

没有答案