[英]Saving transparent (alpha channel) PNG from TImageList
我有一個TImageList
,其中包含透明圖標(32位,帶有alpha通道)。 我想要做的是將基於圖像索引的單個圖標另存為PNG文件,同時保留Alpha通道的透明度。 使用RAD Studio 2010,它具有TPngImage
支持,不需要第三方庫。 使用此處的方法將圖像從PNG“ sprite”圖像加載到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代碼,應該不難翻譯。
是的,您可以從添加了它的TImageList
獲得PNG圖像。 下面的代碼允許您執行此操作!
首先,加PngImage
到您的uses
條款。
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是設置afIgnored
的結果,第二個圖是未設置afIgnored
的結果,允許使用先前設置的afDefined
。
原始圖像是名為圖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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.