如何将包含 TPngImage 的 TImage 保存为位图文件?
How to save a TImage containing a TPngImage as Bitmap file?
在 Delphi 10.4 中,我在 Picture
属性 TImage
。这是 运行 时间的样子:
这是 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
组件消失了(它显然变得不可见!)并且创建的 .bmp 文件的大小为零(0 字节)。
但是,当我执行此代码而不是上面的代码时:
procedure TForm1.btnSaveTImageToBitmapClick(Sender: TObject);
begin
Image1.Picture.SaveToFile('Y:\Downloads\test.bmp');
end;
...那么生成的文件是 .PNG
文件,文件扩展名错误 .BMP
!
那么如何将此图像保存为有效的 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
不包含位图。来自 TPicture.Bitmap
属性 的文档:
Use Bitmap to reference the picture object when it contains a bitmap. If Bitmap is referenced when the picture contains a Metafile or Icon graphic, the graphic won't be converted (Types of Graphic Objects). Instead, the original contents of the picture are discarded and Bitmap returns a new, blank bitmap.
这种方法:
Image1.Picture.SaveToFile('Y:\Downloads\test.bmp');
做的正是它应该做的。它将 Picture.Graphic
as-is(在您的情况下恰好是 PNG 图像)保存到您指定的文件中。您为 PNG 图像选择了一个奇怪的扩展名,但这不是 VCL 尝试纠正的内容。
处理 PNG 透明度
如果 PNG 文件有 alpha 通道,bm.Assign
将非常忠实地创建带有 alpha 通道的位图图像。从某种意义上说,这很好,因为这样您就不会丢失任何信息:您获得的 BMP 包含来自 PNG 的所有图形数据,包括整个 alpha 通道。因此,原则上您可以将此 BMP 渲染到任何背景上,并且看起来和 PNG 一样漂亮。
但另一方面,它毕竟不是那么好。因为几乎没有图像查看器或编辑器支持带 alpha 通道的 BMP。这些应用程序可能会忽略 alpha 通道,有效地使每个像素完全不透明。那看起来会很糟糕。
因此,如果您想创建一个没有 alpha 通道的普通 BMP,您需要使用其 alpha 通道将 PNG“渲染”到您选择的背景上,然后保存 non-transparent 结果.您获得的 BMP 将不包含原始 PNG 的 Alpha 通道,因此您会丢失信息。 BMP 将不透明。例如,如果您将它绘制在白色背景上,那么即使您将它放在屏幕的红色区域,您的 icon/subject 后面也始终会有这个白色矩形。
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;
如果您对默认背景颜色(白色)满意,可以省略带星号 (*) 的行。
在 Delphi 10.4 中,我在 Picture
属性 TImage
。这是 运行 时间的样子:
这是 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
组件消失了(它显然变得不可见!)并且创建的 .bmp 文件的大小为零(0 字节)。
但是,当我执行此代码而不是上面的代码时:
procedure TForm1.btnSaveTImageToBitmapClick(Sender: TObject);
begin
Image1.Picture.SaveToFile('Y:\Downloads\test.bmp');
end;
...那么生成的文件是 .PNG
文件,文件扩展名错误 .BMP
!
那么如何将此图像保存为有效的 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
不包含位图。来自 TPicture.Bitmap
属性 的文档:
Use Bitmap to reference the picture object when it contains a bitmap. If Bitmap is referenced when the picture contains a Metafile or Icon graphic, the graphic won't be converted (Types of Graphic Objects). Instead, the original contents of the picture are discarded and Bitmap returns a new, blank bitmap.
这种方法:
Image1.Picture.SaveToFile('Y:\Downloads\test.bmp');
做的正是它应该做的。它将 Picture.Graphic
as-is(在您的情况下恰好是 PNG 图像)保存到您指定的文件中。您为 PNG 图像选择了一个奇怪的扩展名,但这不是 VCL 尝试纠正的内容。
处理 PNG 透明度
如果 PNG 文件有 alpha 通道,bm.Assign
将非常忠实地创建带有 alpha 通道的位图图像。从某种意义上说,这很好,因为这样您就不会丢失任何信息:您获得的 BMP 包含来自 PNG 的所有图形数据,包括整个 alpha 通道。因此,原则上您可以将此 BMP 渲染到任何背景上,并且看起来和 PNG 一样漂亮。
但另一方面,它毕竟不是那么好。因为几乎没有图像查看器或编辑器支持带 alpha 通道的 BMP。这些应用程序可能会忽略 alpha 通道,有效地使每个像素完全不透明。那看起来会很糟糕。
因此,如果您想创建一个没有 alpha 通道的普通 BMP,您需要使用其 alpha 通道将 PNG“渲染”到您选择的背景上,然后保存 non-transparent 结果.您获得的 BMP 将不包含原始 PNG 的 Alpha 通道,因此您会丢失信息。 BMP 将不透明。例如,如果您将它绘制在白色背景上,那么即使您将它放在屏幕的红色区域,您的 icon/subject 后面也始终会有这个白色矩形。
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;
如果您对默认背景颜色(白色)满意,可以省略带星号 (*) 的行。