Sve*_*sli 8 delphi png metafile
我需要在MetaFileCanvas上透明地绘制PNG.当我绘制到位图(我在屏幕上显示时使用)时这很好用,但是对于打印我需要一个MetaFile.我怎样才能做到这一点?
这是一些演示此问题的代码.将附加的PNG放在某处并更新代码中的路径.
procedure TForm1.Test;
var
vPNG : TPNGImage;
vBMP : TBitmap;
vMeta : TMetafile;
vMetaCanvas : TMetafileCanvas;
LDC : HDC;
begin
vPNG := TPNGImage.Create;
try
vPNG.LoadFromFile('c:\temp\pic\pic.png');
//1. Draw to bitmap. Draw stuff behind PNG to demonstrate transparency
vBMP := TBitmap.Create;
try
vBMP.SetSize(vPNG.Width + 20,vPNG.Height + 20);
vBMP.Canvas.Pen.Color := clLime;
vBMP.Canvas.Pen.Width := 5;
vBMP.Canvas.MoveTo(0,0);
vBMP.Canvas.LineTo(vBMP.Width,vBMP.Height);
vBMP.Canvas.MoveTo(vBMP.Width,0);
vBMP.Canvas.LineTo(0,vBMP.Height);
vBMP.Canvas.Draw(10,10,vPNG); //This is drawn correctly and transparently
Canvas.Draw(10,10,vBMP); //Draw to demo form
finally
vBMP.Free;
end;
//2. Draw to metafile
vMeta := TMetaFile.Create;
try
LDC := GetDC(0);
vMetaCanvas := TMetafileCanvas.Create(vMeta,LDC);
try
vMetaCanvas.Pen.Color := clLime;
vMetaCanvas.Pen.Width := 5;
vMetaCanvas.MoveTo(0,0);
vMetaCanvas.LineTo(vPNG.Width+20,vPNG.Height+20);
vMetaCanvas.MoveTo(vPNG.Width+20,0);
vMetaCanvas.LineTo(0,vPNG.Height+20);
vMetaCanvas.Draw(10,10,vPNG); //Not correct. Can't see the green line
finally
vMetaCanvas.Free;
end;
//Demonstrate that resizing works fine:
Canvas.Draw(10,130,vMeta);
vMeta.MMWidth := vMeta.MMWidth * 2;
Canvas.Draw(150,130,vMeta);
vMeta.MMHeight := vMeta.MMHeight * 2;
Canvas.Draw(400,130,vMeta);
finally
vMeta.Free;
ReleaseDC(0,LDC);
end;
finally
vPNG.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)

可能做到这一点的唯一方法是使用AlphaBlend () 窗口函数。当您将 PNG 转换为 32 位 RGBA 文件时。你需要做什么:
将 PNG 加载到 32 位 BMP 中
将 RGB 值与位图中的 A 值预乘(是 AlphaBlend 调用的先决条件)
for y := 0 to FHeight - 1 do begin
Src := BM.ScanLine[ y ];
Dest := FBitmap.ScanLine[ y ];
for x := 0 to FWidth - 1 do begin
A := Src^; Inc( Src );
Dest^ := MulDiv( Dest^, A, 255 ); Inc( Dest );
Dest^ := MulDiv( Dest^, A, 255 ); Inc( Dest );
Dest^ := MulDiv( Dest^, A, 255 ); Inc( Dest );
Dest^ := A; Inc( Dest );
end;
end;
Run Code Online (Sandbox Code Playgroud)调用 Alphablend,使用源 HDC 作为预乘位图的 Canvas.Handle 和目标句柄作为图元文件画布句柄。
BF.BlendOp := AC_SRC_OVER;
BF.BlendFlags := 0;
BF.SourceConstantAlpha := 255;
BF.AlphaFormat := AC_SRC_ALPHA;
AlphaBlend( Bitmap.Canvas.Handle, X, Y, BM.Width, BM.Height, BM.Canvas.Handle, 0, 0, BM.Width, BM.Height, BF );
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
2353 次 |
| 最近记录: |