繁体   English   中英

如何将包含 TPngImage 的 TImage 保存为 Bitmap 文件?

[英]How to save a TImage containing a TPngImage as Bitmap file?

在 Delphi 10.4 中,我在TImagePicture属性中的 DESIGN-TIME 加载了一个PNG图像(具有 Alpha 通道透明度的 32BPP)。 以下是它在运行时的样子:

在此处输入图像描述

这是TImage组件的副本(可以在设计时粘贴到任何 Delphi VCL 应用程序项目中):

object Image1: TImage
  Left = 46
  Top = 200
  Width = 32
  Height = 32
  AutoSize = True
  Center = True
  Picture.Data = {
    0954506E67496D61676589504E470D0A1A0A0000000D49484452000000200000
    00200806000000737A7AF40000000473424954080808087C086488000006F749
    44415478DAB557694C545714BE33C3BE8A0CEBB096224EA94241B16AACA68520
    6DA1D1D485B00A1421DA0A36A9B64D9AFE68AA69A340451B4A41405903D6A5D4
    0AB4285B59442236884C054640C080EC8475A6DF19670803B40C466F72F3DEBB
    E7DC73BE77EED92EE78083195BB74A87310E872D1E52261E9D6409CD8FD9CB1A
    9CD3EEF66C9B99E11800682FD62F9DBA3F34AE155CD9F212016C788500CCD2FB
    12069002002FB8F2C1336658C9CCCC8C595B5B333E9FCF74747494D827262658
    5F5F1FEBECEC64DDDDDD4C2291BC180011756DCCDDDD9DB9B8B8700C0D0DB781
    F23EE69B988E98AB3149D300A608F32FCCC2D1D1D18AC6C646697D7D3D1B1F1F
    7F7E001D1C4DDE9FF61BB8BABABA2158390E2B38AA625AA9544AE77672727232
    A3ACAC4C72E7CE9DE703D06624E0D55B39D740F146B960311E7C7CEBE2FD1814
    24C0D4126D6DED20ACA5606D06F4C778B791F3D7E211D4D2D2222A2C2C645353
    532B03D0C2B7E5DDB35C2B81A04758F91CCF6A0827538FE15D909E9E3E3A3838
    C8A2A3A3D53435351F81660E3C6E780AC1F32D9EB6E01BC6DC03BF28CECDCD55
    02B12C0091B135EFAEA5300B020EE25C47F4F5F58F40681CBE33E16C41999999
    32566F6F6FE6EAEA7A06B443A07D353636F60D9C541FDF4998FBB13685E9FBF0
    E1C3E24B972E91655403D0A9BB9A57C45FC36EDDBAC56C6C6CC811AF41E07B10
    10505C5C9CAD385B3B3B3BB66FDF3E3FD02E83562A168BDFA9ADAD65BEBEBE4C
    4B4BEB14D663C91260DD585A5A2A229ACA51A008C3D0D0500AC32710C687996D
    9293933B07060664341E8FC76263634DF0ECC1E7087CC3283E3E5E6A6E6E4EC0
    084496DC12B538822D29292992E1E1E19501387AF4A8B58686861842FA6062D3
    C4C44425F6C0C040261008C450640D808EA03FA410B4B5B5657BF7EED5E772B9
    F7C839B13F0CE199565252B23C00B1BA1E2F47DD8C6133B3B7B77F1B024A20A0
    1C7FB89D12CEFC41494A4F4FAF083C9EE0F1E9E8E8B8A170382B2B2B0627F507
    2D934214FB8500285D16C03FE48482D7964F692B1CB0D0F6828282721500D800
    80F085038015BEABA9A939BE2C80475AAB78D70C6CC98918D2F0699830069B63
    E17C090B938A9A9A1A333636FE043CF1E0F901611B035F99A3D3319A98987882
    5E047A596B6BEB0E959D70FDFAF5CCC7C7E7276C8EC0E688FCFCFC54C4B412BB
    A9A929454A1814FD0C9E94F2F2F28FAAAAAAE6E854CC6262622CE00B5DA077F7
    F4F408540680F8673B77EE3C0F2121D81C92969676A1B7B757891DF5821D3E7C
    9852723A78322A2A2A422B2B2B957800500DA1494969020074560A200DC283B1
    3918002EFE078040F06480E70200842C04101212C2B3B0B098067D1200B4570A
    2019C2C3B1393C2F2FEF7C5B5B9B123BF508E1E1E107E445291500221602A023
    803FD111407F8FE5F2D550439F97CB336106060674C671107E849C1085256161
    9D4792A266E563F02490133E7DFA344691296950B644CA563861797B7BFB7625
    00280F7F4F334EA81A93A671197B5D660154C326544395E34BC50100DFDFBE7D
    FBD81C002C34F4E819BF7BD7C2698F437F4781C340E7AF5C297BA3896FC7BB6F
    E9F45212D1D5AB57CB39A79E35A565542A2BAC5D867B579937A949669B843DA2
    68C7818E7CB196D15BBFE959CBCC871856A4E2B2E9E9E91D30B192503A263426
    73A9B8BFBFFFC6CCCC8C8C6664644447A448C522EC5F2B4BC5B1424BE66AA4CB
    2A9E0CB1660B27B679F3E60388E314EEECCCEF82C1EE0FC71EDC1BFFACAC5126
    04C54800211D10D03F32326272EEDC39250001010194F3A929B1C21FBE7AF6EC
    D9564A44541151A8F4F1138DF206251CFDE2F9EBD7AF2B3B1E75B99191915C24
    8A2A307A80311B9D6E007531F0581616164656E801CD140A6C9392923A868686
    647B29CBC1C3F9EAEAEA149BC3C892ABE3E2E2A4F4E7FEFEFE0C8DCC5C399E9D
    9DDD929A9A2A210B2EF27C373737E6E9E9B906CCB59806D81007109F5EB97285
    098542CA8897B1EE47B9A0A8A8E8624343836C1FB5EA50F40180FC02DA1F6848
    BC6EDEBCC976EFDE4DCAE71A12CC8DD5D5D52234AAB27D8B0050BADCB56B1773
    7474F4C62729D3244BE08FA3807804B17E086B67B0968772BB3F2B2B4BB6CFCB
    CB8BC0FF08DA41D0BE84654EA03493D9955A3294F0E29C9C9CB93BC352F731AA
    DBD44030642C6F6CCEC3D49777C35F605266A1223089352B34A583D494464545
    6920C15083608CE982B98E2D684AF103C5D9D9D96C7E815A12000D4A2A7E7E7E
    CCC1C1C1099F19F3DAF276522207F5359CF1243C5D82B38EC45A22FD29E8DDA4
    58CE5F8BBF0DEAEAEA12D131CE57FEBF0014C7E1E1E1C1B66EDDCA8573ADF462
    42ADFB0980CBA8ABAB93504A86F32DD6A18A308AEF4D9B36316767670E2CB30D
    20E65FCD8C481F9B773583F24228AE686E6E96C2E1D8C27CB162008A410D07B5
    DF4B5D4EA9CF479F27BB9CC23919F2FCA25BD052E35F02ED3A5D68222C670000
    000049454E44AE426082}
  Proportional = True
end

现在,在运行时,我尝试将此图像保存为 BITMAP 图像文件 (.bmp):

procedure TForm1.btnSaveTImageToBitmapClick(Sender: TObject);
begin
  Image1.Picture.Bitmap.SaveToFile('Y:\Downloads\test.bmp');
end;

但是当我在运行时执行此代码时,会发生一些非常奇怪的事情: TImage组件消失(它显然变得不可见。)并且 created.bmp 文件的大小为零(0 字节)。

但是,当我执行以下代码而不是上面的代码时:

procedure TForm1.btnSaveTImageToBitmapClick(Sender: TObject);
begin
  Image1.Picture.SaveToFile('Y:\Downloads\test.bmp');
end;

...然后生成的文件是一个带有错误.BMP文件扩展名的.PNG文件!

那么如何将此图像保存为有效的 BITMAP ( .BMP ) 文件?

编辑:@Andreas Rejbrand 和@Remy Lebeau 的回答提供了广泛的解释和解决问题的方法。

您必须创建一个TBitmap并将Picture.Graphic分配给它:

procedure TForm3.btnSaveClick(Sender: TObject);
var
  bm: TBitmap;
begin
  bm := TBitmap.Create;
  try
    bm.Assign(Image1.Picture.Graphic);
    bm.SaveToFile('C:\Users\Andreas Rejbrand\Desktop\bitmap.bmp');
  finally
    bm.Free;
  end;
end;

你的方法:

Image1.Picture.Bitmap.SaveToFile('Y:\Downloads\test.bmp');

不起作用,因为Picture不包含 bitmap。 TPicture.Bitmap属性的文档中:

使用 Bitmap 引用图片 object当它包含 bitmap 时 如果图片包含 Metafile 或 Icon 图形时引用 Bitmap,则该图形不会被转换(图形对象类型)。 相反,图片的原始内容被丢弃,Bitmap 返回一个新的空白 bitmap。

这种方法:

Image1.Picture.SaveToFile('Y:\Downloads\test.bmp');

做它应该做的事情。 它将Picture.Graphic按原样(在您的情况下恰好是 PNG 图像)保存到您指定的文件中。 您为 PNG 图像选择了一个奇怪的扩展名,但这不是 VCL 试图纠正的。

处理 PNG 透明度

如果 PNG 文件有 alpha 通道, bm.Assign将非常忠实地创建一个带有 alpha 通道的 bitmap 图像。 从某种意义上说,这很好,因为这样您就不会丢失任何信息:您获得的 BMP 包含来自 PNG 的所有图形数据,包括整个 alpha 通道。 因此,原则上,您可以将此 BMP 渲染到任何背景上,并且看起来与 PNG 一样漂亮。

但在另一方面,它毕竟不是那么好。 因为几乎没有图像查看器或编辑器支持带有 Alpha 通道的 BMP。 这些应用程序可能会忽略 alpha 通道,从而有效地使每个像素完全不透明。 那会看起来很可怕。

因此,如果您想创建一个没有 Alpha 通道的普通 BMP,您需要使用其 Alpha 通道将 PNG“渲染”到您选择的背景上,然后保存不透明的结果。 您获得的 BMP 将不包含原始 PNG 的 alpha 通道,因此您会丢失信息。 BMP 将不透明。 例如,如果您将它绘制到白色背景上,您的图标/主题后面将始终有这个白色矩形,即使您将它放在屏幕的红色区域也是如此。

procedure TForm3.Image1Click(Sender: TObject);
var
  bm: TBitmap;
begin
  bm := TBitmap.Create;
  try
    bm.SetSize(Image1.Picture.Width, Image1.Picture.Height);
    bm.Canvas.Brush.Color := clSkyBlue;                                {*}
    bm.Canvas.FillRect(Rect(0, 0, bm.Width, bm.Height));               {*}
    bm.Canvas.Draw(0, 0, Image1.Picture.Graphic);
    bm.SaveToFile('C:\Users\Andreas Rejbrand\Desktop\bitmap2_1.bmp');
  finally
    bm.Free;
  end;
end;

如果您对默认背景颜色(白色)感到满意,则可以省略带星号 (*) 的行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM