这是我的代码,我有一个背景图片宽度:245和高度:150和一张png图片128x128,所以我在背景图片中复制部分png图片。
我也有这个信息:
dstX =目的地点的x坐标。
dstY =目的地点的y坐标。
srcX =源点的x坐标。
srcY =源点的y坐标。
srcW =来源宽度。
srcH =来源高度。
我尝试像这样使用copyRect
procedure TMyClass.FillImage;
var
bg,png: TPngImage;
dstX,dstY,srcW,srcH,srcX,srcY: Integer;
begin
bg := TPngImage.CreateBlank(COLOR_RGB,8,245,150);
png := TPngImage.Create;
png.LoadFromFile('C:\temp\example.png');
dstX := 10;dstY:=0;srcW:=0;srcH:=118;srcX:=128;srcY:=10;
bg.Canvas.CopyRect(Rect(dstX,dstY,srcW,srcH),png.Canvas,Rect(srcX,srcY,png.Width,png.Height));
//With this values not working, I have the same result as before, should start copy in position 138 of bg.
dstX := 138;dstY:=0;srcW:=0;srcH:=118;srcX:=10;srcY:=10;
bg.Canvas.CopyRect(Rect(dstX,dstY,srcW,srcH),png.Canvas,Rect(srcX,srcY,png.Width,png.Height));
end;
使用CopyRect,我有两个问题。
背景图片一开始不是png格式,因为它在开头只创建宽度和高度,但最后必须保存为png。
我搜索了这个问题,首先将图像png复制到bg中我试试这个,但没有成功:
http://www.delphitricks.com/source-code/graphic/copy_part_of_one_image_to_another.html
然后我读了透明度问题
Alphablend and TransparentBlt和Why am I losing transparency when calling BitBlt or CopyRect?
但在我的情况下是不同的,因为我没有使用你可以看到的绘图框,并使用png图像,我用上面提供的信息将这个图像的一部分复制到另一个图像中。但也许这篇文章可以激励别人帮助我。
答案 0 :(得分:3)
由于自没有外部设备的Delphi XE2 Delphi支持GDI +,最简单的方法可能是忽略了GDI,因为alpha通道的限制,并直接使用GDI +的可能性。
只需为目标PNG创建所需大小的TGPBitmap
创建提供要绘制的(PNG)文件的TGPImages
使用以TGPBitmap为目标创建的TGPGraphics绘制这些图像,并根据需要在宽度/高度的所需位置绘制图像,GDIPOBJ中有许多带有描述性参数命名的DrawImage重载。
按mime类型选择编码器(例如image / bmp,image / jpeg,image / gif,image / tiff,image / png)并使用此编码器保存文件。
一个简短的例子:
uses PNGImage, GDIPOBJ, GDIPAPI, GDIPUTIL;
const
C_FileName1 = 'C:\temp\red.png';
C_FileName2 = 'C:\temp\Yellow.png';
procedure TDemo.Button1Click(Sender: TObject);
var
gp: TGPGraphics;
bg: TGpImage;
gi1: TGpImage;
gi2: TGpImage;
encoderClsid: TGuid;
begin
bg := TGPBitmap.Create(256, 150);
try
gi1 := TGpImage.Create(C_FileName1);
try
gi2 := TGpImage.Create(C_FileName2);
try
gp := TGPGraphics.Create(bg);
try
gp.DrawImage(gi1, 0, 0, 140, 140);
gp.DrawImage(gi2, 20, 20, 30, 30);
gp.DrawImage(gi2, 70, 70, 50, 50);
// Take one of many overloads to crop the image as desired
//function DrawImage(image: TGPImage; x, y, srcx, srcy, srcwidth, srcheight: Single; srcUnit: TUnit): TStatus; overload;
gp.DrawImage(gi2, 150, 30, 60, 40, 60, 80, UnitPixel);
//function TGPGraphics.DrawImage(image: TGPImage; const destRect: TGPRectF; srcx, srcy, srcwidth, srcheight: Single; srcUnit: TUnit; imageAttributes: TGPImageAttributes = nil; callback: DrawImageAbort = nil; callbackData: Pointer = nil): TStatus;
gp.DrawImage(gi2, DestRect , 60, 40, 60, 80, UnitPixel);
finally
gp.Free
end;
GetEncoderClsid('image/png', encoderClsid);
bg.Save('C:\temp\test.png', encoderClsid, nil);
Image1.Picture.LoadFromFile('C:\temp\test.png');
finally
gi2.Free
end;
finally
gi1.Free
end;
finally
bg.Free;
end;
end;
由于可以在每个画布上使用TGPGraphics(TGPGraphics.Create(aCanvas.Handle)),一看GDIPOBJ,GDIPAPI,GDIPUTIL可能会很有趣。