Delphi 10.4.2中使用TWICImage保存透明BMP出现黑底如何解决
Delphi透明图像转BMP丢失透明效果解决方案
问题原因
你的代码出现透明区域变黑的问题由以下3个错误导致:
- TBitmap的pf32bit模式默认使用预乘alpha格式,TWICImage加载的透明图像默认是非预乘格式,直接Assign会导致alpha值异常,透明区域被填充为黑色
- TWICImage设置输出格式为BMP时,默认不会启用alpha通道写入配置,输出的BMP文件头缺失透明标识
LImageOut.Transparent的设置时机错误,应该在Assign内容之前设置,而非之后
修正代码
procedure TFrmTestGenImg.Resize; var LInputImgPath, LOutputImgPath: string; LImageIn, LImageOut: TWICImage; LBitmap: TBitmap; // 新增WIC启用alpha保存的参数变量 LEncoderOptions: TWPictureEncodingOptions; begin LInputImgPath := 'C:\temp\Input.bmp'; LOutputImgPath := 'C:\temp\Output.bmp'; LImageIn := TWICImage.Create; try LImageIn.Transparent := True; LImageIn.LoadFromFile(Trim(LInputImgPath)); LImageOut := TWICImage.Create; try LBitmap := TBitmap.Create; try LBitmap.PixelFormat := pf32bit; LBitmap.AlphaFormat := afDefined; // 显式指定alpha格式为非预乘,匹配TWICImage LBitmap.Transparent := True; LBitmap.Assign(LImageIn); { 此处替换为支持alpha的缩放逻辑,不要使用默认StretchDraw 推荐用WIC自带的缩放接口或者Graphics32库的缩放方法 } // 提前设置LImageOut的透明属性和输出格式 LImageOut.Transparent := True; LImageOut.ImageFormat := wifBmp; // 显式指定BMP保存时启用alpha通道 LEncoderOptions := LImageOut.EncoderOptions as TWPictureEncodingOptions; LEncoderOptions.BmpOptions.EnableV5Header := True; LEncoderOptions.BmpOptions.AlphaChannel := acPreserve; LImageOut.Assign(LBitmap); LImageOut.SaveToFile(LOutputImgPath); finally LBitmap.Free; end; finally LImageOut.Free; end; finally LImageIn.Free; end; end;
额外注意事项
- 带透明的32位BMP使用BITMAPV5HEADER格式,部分老旧看图软件、工具不支持该格式,若需兼容老环境建议输出为PNG格式
- 缩放操作不要使用TCanvas.StretchDraw,该方法不会处理alpha通道,会直接丢失透明信息,建议直接通过TWICImage的缩放接口完成缩放,无需中转TBitmap
内容的提问来源于stack exchange,提问作者Marina
相关产品推荐
相关产品推荐

