【问题标题】:How to correctly resize transparent image in graphisc32?如何在 graphisc32 中正确调整透明图像的大小?
【发布时间】:2026-02-10 09:00:01
【问题描述】:

图片为橄榄色透明bmp。

type 
  TForm1 = class(TForm)
  ImageList: TImageList;  //
  MainMenu: TMainMenu;    //Standart parameters
  MenuItem: TMenuItem;    //
  procedure FormCreate(Sender: TObject);
...
function ScaleImage(aImage: TBitmap): TBitmap;
var
  Src, Dst: TBitmap32;
  R: TKernelResampler;      
begin
  Src := TBitmap32.Create;
  Src.SetSize(16, 16);
  Src.DrawMode := dmTransparent;
  Src.OuterColor := clOlive;
  Src.Assign(aImage);
  Dst := TBitmap32.Create;
  Dst.SetSize(24,24);
  R := TKernelResampler.Create(Src);
  R.Kernel := TLanczosKernel.Create;
  Dst.DrawMode := dmTransparent;
  Dst.OuterColor := clOlive;
  Dst.Draw(Dst.BoundsRect, Src.BoundsRect, Src);
  Result.Assign(Dst);
end;

procedure AddImage;
var
  Image: TBitmap;
begin
  Image := TBitmap.Create;
  Image.LoadFromResourceName(hInstance,  'BMPNOFILTER');
  ImageList.AddMasked(ScaleImage(Image), clOlive);      
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  AddImage;
  MainMenu.Images := ImageList;
  MenuItem.ImageIndex := 0;
end;

在结果TBitmap 到图像列表TImageListImagelist.AddMasked(Result, clOlive); 之后,但图像是用橄榄色绘制的。 尝试调整没有橄榄色 (aImage.transparent := True;) 的图像大小,在分配 Src 背景后变为黑色并将其用作透明色,忽略 OuterColor 值。

尝试使用 clOlive32 为 OuterColor。结果:

我使用的代码:

var
 R: TKernelResampler;
 Src, Dst: TBitmap32;
 fImage: TBitmap;
 OriginalImage, TranOriginalImage: TImage //16x16
 SrcImage, DstImage, ResultImage: TImage //24x24
...
fImage := TBitmap.Create;
fImage.LoadFromResourceName(hInstance,  'BMPNOFILTER');
OriginalImage.Picture.Bitmap := fImage;
fImage.Transparent := True;
fImage.TransparentColor := clOlive;
TranOriginalImage.Picture.Bitmap := fImage;
TranOriginalImage.Transparent := True;
Src := TBitmap32.Create;
Src.SetSize(16, 16);
Src.OuterColor := clOlive32;
Src.Assign(fImage);
Src.DrawMode := dmTransparent;
Src.OuterColor := clOlive32;
SrcImage.Picture.Bitmap.Assign(Src);
Dst := TBitmap32.Create;
Dst.SetSize(24, 24);
Dst.DrawMode := dmTransparent;
Dst.OuterColor := clOlive32;
R := TKernelResampler.Create(Src);
R.Kernel := TLanczosKernel.Create;
Dst.Draw(Dst.BoundsRect, Src.BoundsRect, Src);
DstImage.Picture.Bitmap.Assign(Dst);
ResultImage.Picture.Bitmap.Assign(Dst);
ResultImage.Transparent := True; 

【问题讨论】:

  • 你能显示真实的代码吗?例如,我们无法判断 Src、Dst、aImage 是参数、全局变量、局部变量还是对象成员。请给我们一个小的、可编译的程序来显示您的问题。
  • 我更新了代码。
  • this question能帮到你吗?
  • @asd-tm 我试过Src.DrawMode:=dmBlendSrc.DrawMode:=dmOpaque 没有结果。也尝试为Dst.DrawMode 做同样的事情。 Src.Assing(aImage)之后的黑色背景。
  • 注意:代码不是 100% 正确,因为它错过了 Result TBitmap 实例的创建。

标签: delphi graphics32


【解决方案1】:

您应该使用橄榄色的 Graphics32 吊坠。这是 clOlive32 而不是 clOlive。随着添加

aImage.transparent := True;

这应该或多或少起到作用。

最终您会看到一些小故障,因为重采样器可能不会将红色保留为红色,而是使用实际重采样来获取边缘之间的颜色。

【讨论】:

  • Src.OuterColorDst.OuterColor 上设置clOlive32,在Src.Assign(aImage) 之前设置Image.Transparent := True。我将在主帖中添加新结果。
  • 在主帖中添加了带有结果的图像。我认为问题在于原始图像的像素格式。加载其值 pf4bit 后。尝试将原始图像保存在 pf32bit 中,所有图像都有橄榄色背景。