Delphi 如何在TMetaFileCanvas上透明地绘制PNG
我需要在MetaFileCanvas上透明地绘制PNG。当我绘制位图(在屏幕上显示时使用位图)时,这可以很好地工作,但打印时需要一个图元文件。我怎样才能做到这一点 下面是一些演示问题的代码。将附加的PNG放在某个地方,并更新代码中的路径Delphi 如何在TMetaFileCanvas上透明地绘制PNG,delphi,png,metafile,Delphi,Png,Metafile,我需要在MetaFileCanvas上透明地绘制PNG。当我绘制位图(在屏幕上显示时使用位图)时,这可以很好地工作,但打印时需要一个图元文件。我怎样才能做到这一点 下面是一些演示问题的代码。将附加的PNG放在某个地方,并更新代码中的路径 procedure TForm1.Test; var vPNG : TPNGImage; vBMP : TBitmap; vMeta : TMetafile; vMetaCanvas : TMetafileCanvas; LDC : HDC
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;
实现这一点的唯一方法可能是使用()windows函数。将PNG转换为32位RGBA文件时。您需要做的是:
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 );
我认为您可以简单地使用函数+1来出色地表示问题。pngimage必须从目标设备上下文中读取,才能透明地绘制源设备上下文中的内容。元文件画布不是实际的绘图表面,它表示可播放的记录。您无法从元文件画布读取像素值,例如“像素[x,y]将返回“-1”@塞塔克:我担心我会得到这样的回答。这意味着它无法完成,我们必须在程序中做很多更改:-/啊,好吧。谢谢:-)跳过元文件。。您可以始终打印位图图像,而不是图元文件。@PA:是的,我们可能不得不这样做,但我希望不会。太多的未知数,主要与缩放有关。(生成的图元文件用于报告中,我们不知道它是填充了整个页面还是只填充了一小部分)
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 );