枚舉 GDI+ 內建圖像編碼器 (用於保存圖片),獲取其 CLSID、格式描述、擴展名、MIME、標志等信息,為 TGPImage.Save 選擇正確編碼器提供依據。
| 函數 | 用途 |
|---|---|
GetImageEncodersSize(out NumEncoders, Size: Cardinal) | 獲取編碼器數量與緩衝區大小 |
GetImageEncoders(NumEncoders, Size: Cardinal; Encoders: PImageCodecInfo) | 填充編碼器信息陣列 |
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type TForm1 = class(TForm)
Memo1: TMemo; btnEnum: TButton;
procedure FormCreate(Sender: TObject);
procedure btnEnumClick(Sender: TObject);
end; var Form1: TForm1;
implementation {$R *.dfm} uses GDIPOBJ, GDIPAPI;
procedure TForm1.FormCreate(Sender: TObject);
begin Memo1.Align:=alClient; Memo1.ScrollBars:=ssBoth; Memo1.Font.Name:='Consolas'; btnEnum.Caption:='枚舉編碼器'; end;
procedure TForm1.btnEnumClick(Sender: TObject);
var Num, Size: Cardinal; CodecInfo: PImageCodecInfo; i: Integer; Arr: array of TImageCodecInfo;
begin
GetImageEncodersSize(Num, Size); GetMem(CodecInfo, Size);
try
GetImageEncoders(Num, Size, CodecInfo);
Memo1.Clear;
for i := 0 to Num - 1 do with Memo1.Lines, Arr(CodecInfo)[i] do
begin
Add(Format('Clsid: {%s}', [GUIDToString(Clsid)]));
Add(Format('FormatID: {%s}', [GUIDToString(FormatID)]));
Add(Format('CodecName: %s', [CodecName]));
Add(Format('FormatDescription: %s', [FormatDescription]));
Add(Format('FilenameExtension: %s', [FilenameExtension]));
Add(Format('MimeType: %s', [MimeType]));
Add(Format('Flags: %d', [Flags]));
Add(Format('Version: %d', [Version]));
Add(Format('SigCount: %d', [SigCount]));
Add(Format('SigSize: %d', [SigSize]));
Add('');
end;
finally FreeMem(CodecInfo); end;
end;
end.
Clsid: {557CF400-1A04-11D3-9A73-0000F81EF32E}
FormatID: {B96B3CAB-0728-11D3-9D7B-0000F81EF32E}
CodecName: Built-in BMP Codec
FormatDescription: BMP
FilenameExtension: *.BMP;*.DIB;*.RLE
MimeType: image/bmp
Flags: 65543
Version: 1
SigCount: 1
SigSize: 2
Clsid: {557CF401-1A04-11D3-9A73-0000F81EF32E}
FormatID: {B96B3CAE-0728-11D3-9D7B-0000F81EF32E}
CodecName: Built-in JPEG Codec
FormatDescription: JPEG
FilenameExtension: *.JPG;*.JPEG;*.JPE;*.JFIF
MimeType: image/jpeg
Flags: 65543
SigCount: 1
SigSize: 2
Clsid: {557CF402-1A04-11D3-9A73-0000F81EF32E}
FormatID: {B96B3CB0-0728-11D3-9D7B-0000F81EF32E}
CodecName: Built-in GIF Codec
FormatDescription: GIF
FilenameExtension: *.GIF
MimeType: image/gif
Flags: 65543
SigCount: 2
SigSize: 6
Clsid: {557CF405-1A04-11D3-9A73-0000F81EF32E}
FormatID: {B96B3CB1-0728-11D3-9D7B-0000F81EF32E}
CodecName: Built-in TIFF Codec
FormatDescription: TIFF
FilenameExtension: *.TIF;*.TIFF
MimeType: image/tiff
Flags: 65543
SigCount: 2
SigSize: 2
Clsid: {557CF406-1A04-11D3-9A73-0000F81EF32E}
FormatID: {B96B3CAF-0728-11D3-9D7B-0000F81EF32E}
CodecName: Built-in PNG Codec
FormatDescription: PNG
FilenameExtension: *.PNG
MimeType: image/png
Flags: 65543
SigCount: 1
SigSize: 8
| 格式 | 解碼器 (讀) | 編碼器 (寫) | 備註 |
|---|---|---|---|
| BMP | ✓ | ✓ | |
| JPEG | ✓ | ✓ | |
| GIF | ✓ | ✓ | |
| TIFF | ✓ | ✓ | |
| PNG | ✓ | ✓ | |
| ICO | ✓ | ✗ | 內建無 ICO 編碼器 |
| EMF/WMF | ✓ | ✗ | 元文件僅解碼 |
uses GDIPUTIL; // 提供 GetEncoderClsid
procedure SaveAsFormat(const Img: TGPImage; const FileName, MimeType: string);
var
EncCLSID: TGUID;
begin
if GetEncoderClsid(MimeType, EncCLSID) then
Img.Save(FileName, EncCLSID)
else
raise Exception.Create('不支持的編碼格式: ' + MimeType);
end;
// 用法
SaveAsFormat(Img, 'output.png', 'image/png');
SaveAsFormat(Img, 'output.jpg', 'image/jpeg');
SaveAsFormat(Img, 'output.tif', 'image/tiff');
function GetEncoderClsid(const MimeType: string; out Clsid: TGUID): Boolean;
var
Num, Size: Cardinal;
Info: PImageCodecInfo;
i: Integer;
Arr: array of TImageCodecInfo;
begin
Result := False;
GetImageEncodersSize(Num, Size);
GetMem(Info, Size);
try
GetImageEncoders(Num, Size, Info);
for i := 0 to Num - 1 do
if SameText(Arr(Info)[i].MimeType, MimeType) then
begin
Clsid := Arr(Info)[i].Clsid;
Result := True;
Break;
end;
finally
FreeMem(Info);
end;
end;
編碼器枚舉是「保存為」功能的基礎設施。內建僅 6 個編碼器 (BMP/JPEG/GIF/TIFF/PNG/...),ICO/EMF/WMF 僅能讀不能寫。掌握 GetImageEncoders 枚舉模板、GetEncoderClsid 查找封裝、Flags 判斷編碼能力,即可構建健壯的多格式圖片導出功能。