我正在使用delphi XE-5,我正在从JSON文件加载按钮信息,以便在TMS ADVToolBar控件上创建按钮。每个按钮为50X35,格式为png,透明度。
我正在获取每个URL,使用idHTTP组件将其检索到流,然后将其加载到png中。然后我把它画到透明的BMP上。但是,我不认为这是正确的方法。无论如何,然后将bmp添加到TImageList,使用索引将其分配给按钮。图像显示在按钮上,但没有透明度。
请参阅下面的代码:
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;
答案 0 :(得分:3)
首先,您必须启用 运行时主题(项目经理),否则您的图片将无透明度。
这是将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;
答案 1 :(得分:2)
我在Delphi 5中有一个旧项目,有时候我还在使用它。 这是我使用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;
在Form(FormCreate)的OnCreate上调用ImageList2Alpha(YourImageList),ImageList将准备存储您的Bitmaps32以保持透明度。
调用LoadPngToBmp过程将PNG转换为Bitmap32,然后将其存储在ImageList中。
答案 2 :(得分:1)
TBitmap
类使用Windows自己的库来操作位图。根据您的Windows版本,底层操作系统库不支持32位BMP,尽管库头文件声明了BITMAPQUAD
结构。
对于较新版本的Windows(Vista及以上版本),字段BITMAPQUAD.reserved
用于存储Alpha通道。对于旧版本,此字段必须保持为零(0x00)。
如果您使用的是“最近”版本的Windows,我看到的唯一可能解释是TBitmap
类未更新以支持Alpha通道。
使用班级TPNGImage
不应成为问题,而不是在使用之前将其转换为BMP,除非您有更具体的需求。
答案 3 :(得分:1)
使用它:
ABitmap.SetSize(png.Width, png.Height);
png.AssignTo(ABitmap);