首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

GDI+ 進階 (101):獲取所有圖像編碼器詳細信息

     編輯:Delphi

目標

枚舉 GDI+ 內建圖像編碼器 (用於保存圖片),獲取其 CLSID、格式描述、擴展名、MIME、標志等信息,為 TGPImage.Save 選擇正確編碼器提供依據。

核心 API (與解碼器對稱)

函數用途
GetImageEncodersSize(out NumEncoders, Size: Cardinal)獲取編碼器數量與緩衝區大小
GetImageEncoders(NumEncoders, Size: Cardinal; Encoders: PImageCodecInfo)填充編碼器信息陣列

完整枚舉代碼 (與 102 幾乎相同,僅 API 名稱不同)


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.

典型輸出 (Windows 10 內建編碼器)

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

關鍵差異:編碼器 vs 解碼器

格式解碼器 (讀)編碼器 (寫)備註
BMP✓✓
JPEG✓✓
GIF✓✓
TIFF✓✓
PNG✓✓
ICO✓✗內建無 ICO 編碼器
EMF/WMF✓✗元文件僅解碼

實戰:根據 MIME 類型查找 Encoder Clsid 並保存


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');

GetEncoderClsid 實現原理 (GDIPUTIL 單元)


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 判斷編碼能力,即可構建健壯的多格式圖片導出功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved