当前位置: 首页 > 知识库问答 >
问题:

从TImageList保存透明(alpha通道)PNG

郜彬
2023-03-14

我有一个包含透明图标(32位,带alpha通道)的TImageList。我想做的是将基于图像索引的单个图标保存为PNG文件,同时保留alpha通道的透明度。使用RAD Studio 2010,因此它具有TPngImage支持,不需要第三方库。图像从PNG“精灵”图像中加载到TImageList中,使用这里的方法——在运行时使用Delphi XE将png图像添加到图像列表中——因此加载时保留透明度。现在我需要单独保存它们,换句话说,从已经加载到TImageList的精灵图像中提取单个图像。

到目前为止,我的代码是:

int imageindex = 123;
boost::scoped_ptr<TPngImage>         png(new TPngImage);
boost::scoped_ptr<Graphics::TBitmap> bmp(new Graphics::TBitmap);

MyImageList->GetBitmap(imageindex, bmp.get()); // Using GetBitmap to copy TImageList image into separate TBitmap

png->Assign(bmp.get()); // Assign that bitmap to TPngImage
png->SaveToFile("C:\\filename.png");

上述方法可以工作,但会以白色背景保存(保存后不会保留透明度)。我可能错过了一个简单的步骤,但无法理解。

Delphi代码也是受欢迎的,应该不难翻译。

共有1个答案

柳景胜
2023-03-14

是的,您可以从添加PNG-映像的TImageList中获取PNG-映像。下面的代码允许您这样做!
首先,将PngImage添加到您的use子句中。

procedure LoadPNGFromImageList(AImageList: TCustomImageList; AIndex: Integer; var ADestPNG: TPngImage);
const
  PixelsQuad = MaxInt div SizeOf(TRGBQuad) - 1;
type
  TRGBAArray = Array [0..PixelsQuad - 1] of TRGBQuad;
  PRGBAArray = ^TRGBAArray;
var
  ContentBmp: TBitmap;
  RowInOut: PRGBAArray;
  RowAlpha: PByteArray;
  X: Integer;
  Y: Integer;
begin
  if not Assigned(AImageList) or (AIndex < 0) or
     (AIndex > AImageList.Count - 1) or not Assigned(ADestPNG)
  then
    Exit;

  ContentBmp := TBitmap.Create;
  try
    ContentBmp.SetSize(ADestPNG.Width, ADestPNG.Height);
    ContentBmp.PixelFormat := pf32bit;

    // Allocate zero alpha-channel
    for Y:=0 to ContentBmp.Height - 1 do
      begin
        RowInOut := ContentBmp.ScanLine[Y];
        for X:=0 to ContentBmp.Width - 1 do
          RowInOut[X].rgbReserved := 0;
      end;
    ContentBmp.AlphaFormat := afDefined;

    // Copy image
    AImageList.Draw(ContentBmp.Canvas, 0, 0, AIndex, true);

    // Now ContentBmp has premultiplied alpha value, but it will
    // make bitmap too dark after converting it to PNG. Setting
    // AlphaFormat property to afIgnored helps to unpremultiply
    // alpha value of each pixel in bitmap.
    ContentBmp.AlphaFormat := afIgnored;

    // Copy graphical data and alpha-channel values
    ADestPNG.Assign(ContentBmp);
    ADestPNG.CreateAlpha;
    for Y:=0 to ContentBmp.Height - 1 do
      begin
        RowInOut := ContentBmp.ScanLine[Y];
        RowAlpha := ADestPNG.AlphaScanline[Y];
        for X:=0 to ContentBmp.Width - 1 do
          RowAlpha[X] := RowInOut[X].rgbReserved;
      end;
  finally
    ContentBmp.Free;
  end;
end;

看这幅画。它描述了如果我们设置或不设置这样的代码行会发生什么:

ContentBmp.AlphaFormat := afIgnored;

原始图像是一个名为图1的图像

在应用程序中使用上述代码:

procedure TForm1.aButton1Click(Sender: TObject);
var
  DestPNG: TPngImage;
begin
  DestPNG := TPNGImage.Create;
  try
    // Initialize PNG
    DestPNG.CreateBlank(COLOR_RGBALPHA, 8, 60, 60);

    // Obtain PNG from image list
    LoadPNGFromImageList(ImageList1, 0, DestPNG);

    // Output PNG onto Canvas
    DestPNG.Draw(Canvas, Rect(0, 0, 60, 60));
    DestPNG.SaveToFile('C:\MyPNGIcon.png');
  finally
    DestPNG.Free;
  end;
end;  
 类似资料:
  • **编辑**我必须导出一个大画布(5Mo 当我导出我的画布(使用toDataUrl)时,它总是返回一个带有alpha通道的. png文件的bas64表示。阿尔法通道权重约为图像数据的25%,我不需要它。 建议的答复: PNG压缩是好的。如果alpha通道是平坦的(所有值都相同),则不会占用太多空间。即使使用完全不透明的alpha通道,也会显示(压缩)。png文件更大。(在一些测试中约为10%) 有

  • 问题内容: 我用来渲染一些文本。我希望文本是半透明的,即具有不为255的alpha值,因此我尝试传递带有alpha值的color参数(例如)作为color参数,但是它没有任何作用。我也尝试在生成的Surface对象上使用,但这也没有执行任何操作。有任何想法吗? 问题答案: 使用模块时,渲染文本时不会考虑文本颜色的Alpha通道,但请参见: 抗锯齿图像被渲染为24位RGB图像。如果背景是透明的,则将

  • 本文向大家介绍Android 颜色透明度(Alpha)级别,包括了Android 颜色透明度(Alpha)级别的使用技巧和注意事项,需要的朋友参考一下 示例 十六进制不透明度值 如果要将45%设置为红色。 红色的十六进制值-#FF0000 您可以在前缀中添加73以实现45%的不透明度-#73FF0000

  • 我正试图重新设计我的网站,使我原来的方形、基于瓷砖的图像渲染更像是图像的剪贴画。。。为了摆脱网格模式。 这是它最初的样子。。。 这是我想要的一个粗略的模型: 所以我重新保存了一个透明背景的图像缩略图。。。我只想让狗展示,正方形是透明的,可以在下面显示网站的背景。 然而,当我在页面上呈现它时,它的背景是黑色的。 我已经检查了我的CSS,看看是否有某种img类,或用于渲染漫画的类。。。甚至可以通过引导

  • 问题内容: 是否可以设置和获取布局的Alpha /不透明度及其所有子视图?我不是在说背景。在相对布局中说出视频控件的集合,例如播放,暂停和进度条。 我可以使用动画淡入淡出,但想知道是否可以使用直接方法。 问题答案: 您可以使用持续时间为0的AlphaAnimation和setFillAfter选项在布局及其子级(或其他任何视图)上设置Alpha。 例: 您可以将一个动画用于多个组件以节​​省内存。

  • 当鼠标不悬停在游戏中时,我试图使游戏中的用户界面透明。但出于某种原因,当我设置图像的alpha值使其变为透明时,什么也没有发生。下面是一些可运行的代码,它复制了问题: 任何帮助都非常感谢!编辑:我收到了一个评论,有人说他们使用了自己的图像,效果很好...当我执行程序时,我会收到这个警告: 是因为我的文件,所以不能正常运行的原因吗?