TPNGObject - 创建一个新的空白图像并在其上绘制半透明图像

Lit*_*per 5 delphi png transparent delphi-7

我正在构建看起来像任何操作系统的应用程序,除了它是一个程序.我有它自己的窗户.输出是TImage.

1)应用程序加载形成皮肤文件到TPNGObject:

皮肤

2)然后应用程序应创建一个新的空白TPNGObject,并将皮肤文件的大小调整为所需的大小,并在该空白图像上绘制它们.应该是这样的:

新形式

3)输出TImage:

产量

问题是我确实知道如何创建空白的屏幕外图像.当然我不能简单地绘制皮肤文件TImage,但是更容易调整皮肤文件的大小并创建一次窗口,而不是每次都绘制TImage(也会达到性能).
我正在使用Gustavo Daud的PNG Library,版本1.564(2006年7月31日).

Ser*_*yuz 5

下面使用CreatePNGMartijn Sally的'pngfunctions.pas'程序,从扩展库(pngcomponents)到pngimage.

var
  Bmp, Mask: TBitmap;
  PNG: TPNGObject;
begin
  Bmp := TBitmap.Create;
  Bmp.PixelFormat := pf24bit;
  Bmp.SetSize(64, 64);

  Bmp.Canvas.Brush.Color := clBtnFace;
  Bmp.Canvas.Font.Color := clRed;
  Bmp.Canvas.Font.Size := 24;
  Bmp.Canvas.TextOut(4, 10, 'text');

  Mask := TBitmap.Create;
  Mask.PixelFormat := pf24bit;
  Mask.Canvas.Brush.Color := clBlack;
  Mask.SetSize(64, 64);
  Mask.Canvas.Font.Color := clWhite;
  Mask.Canvas.Font.Size := 24;
  Mask.Canvas.TextOut(4, 10, 'text');

  PNG := TPNGObject.Create;
  CreatePNG(Bmp, Mask, PNG, False);
  PNG.Draw(Canvas, Rect(10, 10, 74, 74));

  // finally, free etc...
Run Code Online (Sandbox Code Playgroud)


这是输出(黑色,白色方块是TShapes):

在此输入图像描述

  • 这里没有人是坏人,只是缺乏细节导致缺乏帮助. (3认同)

Lit*_*per 2

我向人们道歉,因为我搞乱了他们的头脑。

事实证明,CreateBlank效果如愿。问题是我在 PNG 画布上绘制 PNG ( PNG.Canvas.Draw)。Canvas并不真正支持透明度。要在另一个 PNG 上绘制半透明 PNG,您需要一个将这两个图层合并在一起的过程/函数。经过一些谷歌搜索,我最终得到了这个过程:

procedure MergePNGLayer(Layer1, Layer2: TPNGObject; Const aLeft, aTop: Integer);
var
  x, y: Integer;
  SL1,  SL2,  SLBlended: pRGBLine;
  aSL1, aSL2, aSLBlended: PByteArray;
  blendCoeff: single;
  blendedPNG, Lay2buff: TPNGObject;
begin
  blendedPNG := TPNGObject.Create;
  blendedPNG.Assign(Layer1);
  Lay2buff:=TPNGObject.Create;
  Lay2buff.Assign(Layer2);
  SetPNGCanvasSize(Layer2, Layer1.Width, Layer1.Height, aLeft, aTop);
  for y := 0 to Layer1.Height - 1 do
  begin
    SL1 := Layer1.Scanline[y];
    SL2 := Layer2.Scanline[y];
    aSL1 := Layer1.AlphaScanline[y];
    aSL2 := Layer2.AlphaScanline[y];
    SLBlended := blendedPNG.Scanline[y];
    aSLBlended := blendedPNG.AlphaScanline[y];
    for x := 0 to Layer1.Width - 1 do
    begin
      blendCoeff:=aSL1[x] * 100/255/100;
      aSLBlended[x] := round(aSL2[x] + (aSL1[x]-aSL2[x]) * blendCoeff);
      SLBlended[x].rgbtRed   := round(SL2[x].rgbtRed + (SL1[x].rgbtRed-SL2[x].rgbtRed) * blendCoeff);
      SLBlended[x].rgbtGreen := round(SL2[x].rgbtGreen + (SL1[x].rgbtGreen-SL2[x].rgbtGreen) * blendCoeff);
      SLBlended[x].rgbtBlue  := round(SL2[x].rgbtBlue + (SL1[x].rgbtBlue-SL2[x].rgbtBlue) * blendCoeff);
    end;
  end;
  Layer1.Assign(blendedPNG);
  Layer2.Assign(Lay2buff);
  blendedPNG.Free;
  Lay2buff.Free;
end;
Run Code Online (Sandbox Code Playgroud)


用法:

var
  PNG1, PNG2: TPNGObject;
begin
  PNG1 := TPNGObject.CreateBlank(COLOR_RGBALPHA, 16, 500, 500);
  PNG2 := TPNGObject.Create;
  PNG2.LoadFromFile('...*.png');
  MergePNGLayer(PNG1, PNG2, 0, 0);
  // PNG1 is the output
Run Code Online (Sandbox Code Playgroud)

再次,对于那些想要提供帮助但由于不理解我而无法提供帮助的用户,我感到非常抱歉。