首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Delphi中复制另一部分图像而不丢失透明度

如何在Delphi中复制另一部分图像而不丢失透明度
EN

Stack Overflow用户
提问于 2015-01-07 11:32:50
回答 1查看 3.3K关注 0票数 2

这是我的代码,我有一个背景图片宽度: 245和高度: 150和一张png图片128x128,所以我在背景图片中复制部分png图片。

我也有以下资料:

dstX =x-目标点坐标。

dstY =y-目标点坐标。

srcX =x-源点坐标。

srcY =y-源点坐标。

srcW =源宽度。

srcH =源高度。

我试着像这样使用copyRect

代码语言:javascript
运行
复制
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,我有两个问题。

  1. 当destX大于png图片时,它不会在背景图片bg中的正确位置开始复制。这是主要问题。
  2. 我失去了透明度。

背景图片在开始时不必是png格式,因为它是在开始时创建的,只有宽度和高度,但最后必须保存为png。

我搜索这个问题,首先复制bg内部的图像png,我尝试了这个,但没有成功:

another.html

那么关于我读到的透明度问题

Alphablend and TransparentBltWhy am I losing transparency when calling BitBlt or CopyRect?

但是在我的例子中是不同的,因为我没有像你看到的那样使用画盒,并且使用一个png图像,我用上面的信息在另一个图像中复制这个图像的一部分。但也许这篇文章能激励别人帮助我。

EN

回答 1

Stack Overflow用户

发布于 2015-01-07 22:02:04

由于Delphi XE2 Delphi没有外部单元而支持GDI+,最简单的方法可能是由于α通道的限制而忽略GDI,并直接使用GDI+的可能性。

只需为目标PNG创建一个所需大小的TGPBitmap即可。

创建TGPImages,提供要绘制的(PNG)文件。

使用以TGPGraphics为目标创建的TGPBitmap绘制这些图像,并按您喜欢的宽度/高度在所需的位置绘制图像,GDIPOBJ中有许多带有描述性参数命名的DrawImage重载。

按mime类型选择编码器(例如,图像/bmp、图像/jpeg、图像/gif、图像/tiff、图像/png)并使用此编码器保存文件。

一个简短的例子:

代码语言:javascript
运行
复制
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。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27818545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档