Delphi png到bmp转换(保持透明度)
我使用delphi XE-5,从JSON文件加载按钮信息,以便在TMS ADVToolBar控件上创建按钮。每个按钮为50X35,png格式,透明 我获取每个url,使用idHTTP组件将其检索到流中,然后将其加载到png中。然后我把它画到一个透明的BMP上。然而,我认为这不是正确的方法。无论如何,bmp会被添加到TImageList中,并使用索引将其分配给按钮。图像显示在按钮上,但没有透明度 请参见下面的我的代码:Delphi png到bmp转换(保持透明度),delphi,delphi-xe5,Delphi,Delphi Xe5,我使用delphi XE-5,从JSON文件加载按钮信息,以便在TMS ADVToolBar控件上创建按钮。每个按钮为50X35,png格式,透明 我获取每个url,使用idHTTP组件将其检索到流中,然后将其加载到png中。然后我把它画到一个透明的BMP上。然而,我认为这不是正确的方法。无论如何,bmp会被添加到TImageList中,并使用索引将其分配给按钮。图像显示在按钮上,但没有透明度 请参见下面的我的代码: imgUrl:= //code to get img url from JS
imgUrl:= //code to get img url from JSON file;
MS := TMemoryStream.Create;
png := TPngImage.Create;
png.Transparent:= True;
try
idHTTP1.get(imgUrl,MS);
Ms.Seek(0,soFromBeginning);
png.LoadFromStream(MS);
bmp:= TBitmap.Create;
bmp.Transparent:= True;
bmp.Width:= 50;
bmp.Height:= 50;
png.Draw(bmp.Canvas, Rect(7, 7, png.Width, png.Height));
ImageList1.Add(bmp, nil);
AdvGlowBtn.Images:= ImageList1;
AdvGlowBtn.Layout:= blGlyphTop;
AdvGlowBtn.WordWrap:= False;
AdvGlowBtn.AutoSize:= True;
AdvGlowBtn.ImageIndex:= ImageList1.Count-1;
bmp.Free;
finally
FreeAndNil(png);
FreeAndNil(MS);
end;
TBitmap
类使用Windows自己的库来操作位图。根据您的Windows版本,底层操作系统库不支持32位BMP,尽管库头文件声明了BITMAPQUAD
struct
对于较新版本的Windows(Vista及以上afaik),字段BITMAPQUAD.reserved
用于存储alpha通道。对于旧版本,此字段必须保持为零(0x00)
如果您使用的是“最新”版本的Windows,我看到的唯一可能的解释是,TBitmap
类没有更新以支持alpha通道
使用类
TPNGImage
不应该成为问题,而应该在使用前将其转换为BMP,除非您有一些更具体的需求。首先您必须启用运行时主题(项目管理器),否则您的图像将没有透明度
这是将PNG图像加载到ImageList1
bmp := TBitmap.Create;
try
// everything done before to bmp has no effect
bmp.Assign( png );
// if for some reason the loaded image is smaller
// set the size to avoid the invalid image size error
bmp.Width := ImageList1.Width;
bmp.Height := ImageList1.Height;
AdvGlowBtn.Images:= ImageList1;
...
// now add the Bitmap to the ImageList
AdvGlowBtn.ImageIndex := ImageList1.Add( bmp, nil );
finally
bmp.Free;
end;
我有一个Delphi5中的老项目,我有时仍在使用它。 这是我使用png对象的解决方案
procedure ImageList2Alpha(const ImageList: TImageList);
const
Mask: array[Boolean] of Longint = (0, ILC_MASK);
var
TempList: TImageList;
begin
if Assigned(ImageList) then
begin
TempList := TImageList.Create(nil);
try
TempList.Assign(ImageList);
with ImageList do
begin
Handle := ImageList_Create(Width, Height, ILC_COLOR32 or Mask[Masked], 0, AllocBy);
if not HandleAllocated then
raise EInvalidOperation.Create(SInvalidImageList);
end;
Imagelist.AddImages(TempList);
finally
FreeAndNil(TempList);
end;
end;
end;
procedure LoadPngToBmp(var Dest: TBitmap; AFilename: TFilename);
type
TRGB32 = packed record
B, G, R, A : Byte;
end;
PRGBArray32 = ^TRGBArray32;
TRGBArray32 = array[0..0] of TRGB32;
type
TRG24 = packed record
rgbtBlue, rgbtGreen, rgbtRed : Byte;
end;
PRGBArray24 = ^TPRGBArray24;
TPRGBArray24 = array[0..0] of TRG24;
type
TByteArray = Array[Word] of Byte;
PByteArray = ^TByteArray;
TPByteArray = array[0..0] of TByteArray;
var
BMP : TBitmap;
PNG: TPNGObject;
x, y: Integer;
BmpRow: PRGBArray32;
PngRow : PRGBArray24;
AlphaRow: PByteArray;
begin
Bmp := TBitmap.Create;
PNG := TPNGObject.Create;
try
if AFilename <> '' then
begin
PNG.LoadFromFile(AFilename);
BMP.PixelFormat := pf32bit;
BMP.Height := PNG.Height;
BMP.Width := PNG.Width;
if ( PNG.TransparencyMode = ptmPartial ) then
begin
for Y := 0 to BMP.Height-1 do
begin
BmpRow := PRGBArray32(BMP.ScanLine[Y]);
PngRow := PRGBArray24(PNG.ScanLine[Y]);
AlphaRow := PByteArray(PNG.AlphaScanline[Y]);
for X := 0 to BMP.Width - 1 do
begin
with BmpRow[X] do
begin
with PngRow[X] do
begin
R := rgbtRed; G := rgbtGreen; B := rgbtBlue;
end;
A := Byte(AlphaRow[X]);
end;
end;
end;
end else
begin
for Y := 0 to BMP.Height-1 do
begin
BmpRow := PRGBArray32(BMP.ScanLine[Y]);
PngRow := PRGBArray24(PNG.ScanLine[Y]);
for X := 0 to BMP.Width - 1 do
begin
with BmpRow[X] do
begin
with PngRow[X] do
begin
R := rgbtRed; G := rgbtGreen; B := rgbtBlue;
end;
A := 255;
end;
end;
end;
end;
Dest.Assign(BMP);
end;
finally
Bmp.Free;
PNG.Free;
end;
end;
过程ImageList2Alpha(常量ImageList:TImageList);
常数
掩码:Longint=(0,ILC_掩码)的数组[布尔值];
变量
圣殿骑士:提摩日骑士;
开始
如果已分配(图像列表),则
开始
templast:=TImageList.Create(nil);
尝试
圣堂武士分配(图像列表);
用ImageList做什么
开始
句柄:=ImageList_Create(宽度、高度、ILC_颜色32或掩码[Masked],0,AllocBy);
如果未手动分配,则
引发EINValidoOperation.Create(SinValidImage列表);
结束;
Imagelist.AddImages(圣殿骑士);
最后
FreeAndNil(圣殿骑士);
结束;
结束;
结束;
过程装入pngtobmp(var Dest:TBitmap;AFilename:TFilename);
类型
TRGB32=压缩记录
B、 G,R,A:字节;
结束;
PRGBArray32=^TRGBArray32;
TRGBArray32=TRGB32的数组[0..0];
类型
TRG24=打包记录
rgbtBlue、rgbtGreen、rgbtRed:字节;
结束;
PRGBArray24=^TPRBarray24;
TrpgBarray24=TRG24的数组[0..0];
类型
TByteArray=字节的数组[字];
PByteArray=^TByteArray;
TPByteArray=TByteArray的数组[0..0];
变量
BMP:TBitmap;
PNG:TPNGObject;
x、 y:整数;
BMP船头:PRGBArray32;
PngRow:PRGBArray24;
AlphaRow:PByte阵列;
开始
Bmp:=TBitmap.Create;
PNG:=TPNGObject.Create;
尝试
如果文件名为“”,则
开始
LoadFromFile(AFilename);
BMP.PixelFormat:=pf32位;
BMP.Height:=PNG.Height;
BMP.Width:=PNG.Width;
如果(PNG.TransparencyMode=ptmPartial),则
开始
对于Y:=0到BMP.Height-1 do
开始
BmpRow:=PRGBArray32(BMP.ScanLine[Y]);
PngRow:=PRGBArray24(PNG.ScanLine[Y]);
AlphaRow:=PByteArray(PNG.AlphaScanline[Y]);
对于X:=0到BMP.Width-1 do
开始
用BmpRow[X]do
开始
使用PngRow[X]do
开始
R:=rgbtRed;G:=rgbtGreen;B:=rgbtBlue;
结束;
A:=字节(字母行[X]);
结束;
结束;
结束;
结束其他
开始
对于Y:=0到BMP.Height-1 do
开始
BmpRow:=PRGBArray32(BMP.ScanLine[Y]);
PngRow:=PRGBArray24(PNG.ScanLine[Y]);
对于X:=0到BMP.Width-1 do
开始
用BmpRow[X]do
开始
使用PngRow[X]do
开始
R:=rgbtRed;G:=rgbtGreen;B:=rgbtBlue;
结束;
A:=255;
结束;
结束;
结束;
结束;
目的地分配(BMP);
结束;
最后
Bmp.Free;
巴布亚新几内亚免费;
结束;
结束;
在表单(FormCreate)的OnCreate上调用ImageList2Alpha(YourImageList),ImageList将准备好存储位图32并保持透明度
调用LoadPngToBmp过程将PNG转换为位图32,然后将其存储在ImageList中。如下所示:
ABitmap.SetSize(png.Width, png.Height);
png.AssignTo(ABitmap);
您大概不希望
透明。您可能想要一个32bpp的位图。为什么不直接使用PNG而不是将其转换为BMP?请尝试GraphicEx或Vampyre Imaging。。。但最重要的是使用PNGdirectly@Arioch,没有第三方也一样简单。。。但是直接添加PNGs是最好的选择。@TLama-这是真的吗?TImageList的字形大小必须是成比例的,不是吗。(例如50X50)在这种情况下,来自互联网的图像是50X35。我得到无效的图像大小错误。我很确定XP支持位图中的alpha。而不是win2k。更具体的需求在最初的帖子中列出。如何将50X35 png放入ImageList并保持其透明度,以便我可以将其放置在button@LuvRAD文档声明支持它,但正如您所注意到的,无法将TPNGImage
直接添加到TImageList
中。我觉得缺乏文件令人不安。这很可能是一个很好的解决方案,但对我不起作用,因为我没有提到我的png图像有各种大小(最大的是50X35)。对不起,我只能回答问题。现在您知道了如何在不失去透明度的情况下将PNG转换为位图。如果你有其他问题,那么你应该问另一个问题。这很有效。:)及