Delphi Programming / Object Pascal
[掲載 2013年01月06日] [更新 2013年01月06日] GDI+ 関係サンプル
GDI+ 関係サンプル
G150_JPEG 画像保存時の品質設定
動作確認等
Windows 7 U64(SP1) + Delphi XE(UP1) Pro
G150_GDIPlus_JPEGQuality.zip [841 KB] 2013年01月06日版 (EXE 同梱)
TGPImage ( TGPBitmap ) 保存時の TEncoderParameter
画像の保存用の TGPImage.Save または TGPBitmap.Save メソッドには,エンコードパラメータと呼ばれる,TEncoderParameter レコード型の値を引数にもつオーバーロード関数があります.
このエンコードパラメータには,次の表の値を使用します.
表1
TEncoderParameter (EncoderParameter レコード型) のメンバー
GUID
変換の種別を意味する TGUID 値で,表2 の値
NumberOfValues
Value に設定する値の数で 符号なし32ビット整数値 (ULONG, Cardinal)
Value に設定する要素数
Type_
Value の型で,表3 のいずれかの値
Value
実際に設定する値のポインタ.表4 の値のいずれか,または実際の値
表2
EncoderParameter の GUID の値
GUID の値に応じて Value の値を取得または設定する種類.その Value の値の型を Type_ で指定
EncoderCompression
圧縮率
EncoderColorDepth
色のビット深さ.image/tiff 用
EncoderScanMethod
スキャン方式 (インターレスまたはノンインターレス)
事実上 GDI+ 1.0 では使用不可
EncoderVersion
バージョン
EncoderRenderMethod
レンダリングのプログレッシブモードの設定
事実上 GDI+ 1.0 では使用不可
EncoderQuality
画質・品質
EncoderTransformation
画像の回転,反転の状態.image/jpeg 用
EncoderLuminanceTable
要素数 64 (ShorInt) の輝度テーブル.image/jpeg 用
クロミナンスとルミナンスの両方のテーブルの指定が必要
EncoderChrominanceTable
要素数 64 (ShortInt) の彩度ステーブル.image/jpeg 用
クロミナンスとルミナンスの両方のテーブルの指定が必要
EncoderSaveFlag
フラグ保存.形式の異なる複数の画像を単一の画像に保存
MSDN の Creating and Saving a Multiple-Frame Image 参照
(複数の画像形式を 1 つの TIFF ファイルに保存するサンプル)
CodecIImageBytes
メモリ設定 (?).詳細は不明
表3
EncoderParameter の Type_ の値
EncoderParameterValueTypeByte
符号なし 8bit整数形式 (Byte, PByte)
EncoderParameterValueTypeASCII
1 つの文字が 8bit の ASCII Null 終端文字
EncoderParameterValueTypeShort
16 ビット符号なし整数 (Word, PWord)
EncoderParameterValueTypeLong
32 ビット符号なし整数 (LongWord, PLongWord)
EncoderParameterValueTypeRational
分数形式の 2 つの 32bit整数
EncoderParameterValueTypeLongRange
整数の範囲を意味する 2 つの 32bit 整数値
EncoderParameterValueTypeUndefined
8 ビット整数と解釈する (ShortInt, PShortInt)
EncoderParameterValueTypeRationalRange
2 つの分数形式で,32bit 整数値
表4
EncoderParameter の Value の値
回転した画像は,幅と高さはそのままで,その領域内での回転となる
EncoderValueColorTypeCMYK
CMYK カラー形式 .GDI+ 1.0 は未実装
EncoderValueColorTypeYCCK
YCCK カラー形式.GDI+ 1.0 は未実装
EncoderValueCompressionLZW
LZW 圧縮スキーム (TIFF)
EncoderValueCompressionCCITT3
CCITT3 圧縮スキーム (TIFF)
EncoderValueCompressionCCITT4
CCITT4 圧縮スキーム (TIFF)
EncoderValueCompressionRle
RLE 圧縮スキーム (TIFF)
EncoderValueCompressionNone
無圧縮 (TIFF)
EncoderValueScanMethodInterlaced
インターレス .GDI+ 1.0 は未実装
EncoderValueScanMethodNonInterlaced
ノンインターレス .GDI+ 1.0 は未実装
EncoderValueVersionGif87
GIF87 ファイル形式.GDI+ 1.0 は未実装
EncoderValueVersionGif89
GIF89 ファイル形式.GDI+ 1.0 は未実装
EncoderValueRenderProgressive
プログレッシブレンダリング.GDI+ 1.0 は未実装
EncoderValueRenderNonProgressive
ノンプログレッシブレンダリング.GDI+ 1.0 は未実装
EncoderValueTransformRotate90
時計回りに 90 度回転した画像 (JPEG)
EncoderValueTransformRotate180
時計回りに 180 度回転した画像 (JPEG)
EncoderValueTransformRotate270
時計回りに 270 度回転した画像 (JPEG)
EncoderValueTransformFlipHorizontal
左右反転画像 (JPEG)
EncoderValueTransformFlipVertical
上下反転画像 (JPEG)
EncoderValueMultiFrame
マルチフレーム画像 (TIFF)
EncoderValueLastFrame
マルチフレームの最後のフレーム (TIFF)
EncoderValueFlush
複数フレームのファイルやストリームを閉じる (TIFF)
EncoderValueFrameDimensionTime
フレームの時間設定 (TIFF).GDI+ 1.0 は未実装
EncoderValueFrameDimensionResolution
フレームの解像度 (TIFF).GDI+ 1.0 は未実装
EncoderValueFrameDimensionPage
フレームのページ設定 (TIFF).GDI+ 1.0 は未実装
エンコードパラメータを使用して,JPEG 画像の品質を設定して保存するサンプルです.
ディスクには保存していません.メモリストリームに保存し,比較のために,元の画像と並べて表示するようにしています.
複数のパラメータの同時設定もできるようですが,実際には,TEncoderParameters を再定義して,メモリ領域を確保してやる必要があるようです.
値の設定にトラックバーを使用していますが,サンプル画像のサイズが小さいので,連続的に変化できますが,大きなサイズの画像では,レスポンスが悪くなります.
図1
設計時画面
図2
実行例
copy code
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, ComCtrls, StdCtrls, GDIPOBJ, GDIPAPI, GDIPUTIL, ExtDlgs,
ActiveX;
type
TMyPanel = class (TCustomPanel)
private
FImageFilePath : String ;
FJPEGQuality : Cardinal;
procedure SetImageFilePath(const Value: String );
procedure SetJPEGQuality(const Value: Cardinal);
protected
procedure Paint; override ;
public
constructor Create(AOwner: TComponent); override ;
property ImageFilePath : String read FImageFilePath write SetImageFilePath;
property JPEGQuality : Cardinal read FJPEGQuality write SetJPEGQuality;
end ;
TForm1 = class (TForm)
Button1: TButton;
OpenPictureDialog1: TOpenPictureDialog;
TrackBar1: TTrackBar;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
private
{ Private 宣言 }
MyPanel : TMyPanel;
protected
public
{ Public 宣言 }
end ;
var
Form1: TForm1;
implementation
uses
JPEG,
GifImg,
pngimage;
{$R *.dfm}
// =============================================================================
// フォーム生成時の処理
// =============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Self.Caption := 'GDI+ JPEG 画像の品質設定' ;
// TMyPanelを生成して配置
MyPanel := TMyPanel.Create(Self);
with MyPanel do begin
Parent := Self;
Left := 5 ;
Top := 35 ;
Width := Self.ClientWidth - 10 ;
Height := Self.ClientHeight - Top - 5 ;
Anchors := [akLeft, akTop, akRight, akBottom];
Color := clWhite;
BevelOuter := bvNone;
ParentBackground := False;
DoubleBuffered := True;
end ;
// 品質の設定用
with TrackBar1 do begin
ShowSelRange := False;
TickStyle := tsNone;
Height := 26 ;
Min := 0 ;
Max := 100 ;
Position := 100 ;
end ;
end ;
// =============================================================================
// [画像ファイル]ボタン
// =============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
if not Assigned(MyPanel) then exit;
if OpenPictureDialog1.InitialDir = '' then begin
OpenPictureDialog1.InitialDir := ExtractFileDir(ParamStr(0 ));
end ;
OpenPictureDialog1.Filter := '画像ファイル|*.png;*.jpg;*.jpeg;*.bmp;*.gif' ;
if OpenPictureDialog1.Execute then begin
OpenPictureDialog1.InitialDir := ExtractFileDir(MyPanel.ImageFilePath);
MyPanel.ImageFilePath := OpenPictureDialog1.FileName;
end ;
end ;
// =============================================================================
// TrackBar1のOnChangeイベント処理
// =============================================================================
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
if not Assigned(MyPanel) then exit;
MyPanel.JPEGQuality := TrackBar1.Position;
Label1.Caption := IntToStr(TrackBar1.Position);
end ;
{ TMyPanel }
// -----------------------------------------------------------------------------
// コンストラクタ
// -----------------------------------------------------------------------------
constructor TMyPanel.Create(AOwner: TComponent);
begin
inherited ;
FImageFilePath := '' ;
FJPEGQuality := 100 ;
end ;
// -----------------------------------------------------------------------------
// ImageFilePathプロパティの設定メソッド
// 表示する画像ファイルを指定する
// -----------------------------------------------------------------------------
procedure TMyPanel.SetImageFilePath(const Value: String );
begin
if not FileExists(Value) then exit;
FImageFilePath := Value;
Invalidate;
end ;
// -----------------------------------------------------------------------------
// JPEGQualityプロパティの設定メソッド
// -----------------------------------------------------------------------------
procedure TMyPanel.SetJPEGQuality(const Value: Cardinal);
begin
if FImageFilePath = '' then exit;
if FJPEGQuality <> Value then begin
FJPEGQuality := Value;
Invalidate;
end ;
end ;
// -----------------------------------------------------------------------------
// TMyPanelクラスのPaintメソッド
// 実際の描画コード
// -----------------------------------------------------------------------------
procedure TMyPanel.Paint;
var
LObjWidth : Integer;
LObjHeight : Integer;
LGPImage : TGPImage;
LGPGraphic : TGPGraphics;
LEncoderParams : TEncoderParameters;
LMemoryStream : TMemoryStream;
LIStrema : IStream;
LImageGUID : TGUID;
begin
inherited ;
if FImageFilePath = '' then exit;
// 画像ファイルからTGPImageのインスタンスを生成.幅と高さを取得
LGPImage := TGPImage.Create(FImageFilePath);
LObjWidth := LGPImage.GetWidth;
LObjHeight := LGPImage.GetHeight;
// 画像をTMyPanelのCanvasに描画
LGPGraphic := TGPGraphics.Create(Canvas.Handle);
LGPGraphic.DrawImage(LGPImage, 0 , 0 , LObjWidth, LObjHeight);
// JPEGの品質関係の値をTEncoderParametersレコード型の各メンバーにセット
LEncoderParams.Count := 1 ;
LEncoderParams.Parameter[0 ].Guid := EncoderQuality;
LEncoderParams.Parameter[0 ].Type_ := EncoderParameterValueTypeLong;
LEncoderParams.Parameter[0 ].NumberOfValues := 1 ;
LEncoderParams.Parameter[0 ].Value := @FJPEGQuality;
LMemoryStream := TMemoryStream.Create;
try
// メモリストリームを生成して,そこに保存
GetEncoderClsid('image/jpeg' , LImageGUID);
LGPImage.Save(TStreamAdapter.Create(LMemoryStream), LImageGUID, @LEncoderParams);
LGPImage.Free;
// 保存したJPEG画像を読み出して描画
LIStrema := TStreamAdapter.Create(LMemoryStream);
LGPImage := TGPBitmap.Create(LIStrema);
LGPGraphic.DrawImage(LGPImage, LObjWidth + 10 , 0 , LObjWidth, LObjHeight);
finally
LMemoryStream.Free;
end ;
LGPImage.Free;
LGPGraphic.Free;
end ;
end .
02_ 画像処理のテスト用画像とレナ ( Lenna ) の画像
GDI+ 関係のサンプルプログラムでは使用していませんが,画像処理の研究等によく利用される「標準画像」と言われるテスト用画像があります.その一部が下図の画像類です.
画像処理の関係者以外でも,画像処理関係の参考書を読んだことがある方は,おそくら見たことがあるかも知れません.特に,最後のレナと呼ばれている画像は,
フォーカス合っている人物像と,フォーカスが外れた背景領域の両方がある
背景も単調な壁ではなく,鏡や斜めの「構造」が含まれている
高周波 (帽子の飾りや髪) 領域と,低周波 (腕や背景) 領域の両方を含んでいる
等の理由で使用されています.また,グレイスケール化した画像もよく使われているようです.
これらの元画像は,提供元の Signal and Image Processing Institute
のサイトからダウンロードできます.
他の方,あるいは,別の処理方法と処理結果を比較する必要がある場合は,これらの標準画像を使用するといいでしょう.
[注意]
下図の画像も含めて,当サイトの画像は,拡張子を除いたファイル名で管理している都合上,極一部を除いて全て 256 色の gif 画像となっています.したがって,画像処理のサンプル画像としては決して適切とは言えません.
下図の画像が必要な場合は,参考リンクから入手してください.ただし,参考リンクから入手した医用画像には,グレースケール (白黒・モノクロ) の 256, 512, 1024 等の階調の画像もあります.これはセンサーの分解能による違いです.
図3
ガール (Girl)
図4
マンドリル (Mandrill)
図5
パロッツ (Parrots)
図6
レナ (lenna)