Delphi Programming / Object Pascal
[掲載 2012年11月23日] [更新 2022年10月29日] GDI+ 関係サンプル |
GDI+ 関係サンプル
G030_画像の拡大・縮小時の補間モード |
動作確認等 |
Windows 7 U64(SP1) + Delphi XE(UP1) Pro
一部,Windows 10 ビルド 19043 Pro 64 bit + Delphi XE5(UP2) Pro VCL-32 |
|
G030_GDIPlus_Interpolation.zip [2.2 MB] 2022年10月29日版 (EXE 同梱) |
01_図形描画と画像の拡大・縮小時における補間モード |
図形や画像をリサイズして拡大縮小すると,一般的には描画が劣化します.このため,通常はアンチエイリアスの処理としてピクセル間の補間を行います.GDI+ では画像や図形のリサイズの際にデフォルトのアンチエイリアス処理を行ってくれますが,TGPGraphics では,SetInterpolationMode という関数を使用して,補間のアルゴリズムを指定して補間することができます.そのテストです.
補間のモードは TInterpolationMode 型の列挙型となっています.次の値があります.
ニアレストネイバー法は,単純に元の画像の画素を増したり,間引きする方式です.ジャギー (ギザギサ) が目立ちやすく階調のある画像のリサイズには向いていなと言われています.
バイリニア法,バイキュービック法は周辺の複数の画素を数学的に考慮して処理するので,時間はかかりますが,一般に高品質の結果が得られます.結果の品質は,画像の種類にもよりす.
本サンプルはビットマップ画像でテストしています.直線や曲線等,図形の描画の時のアンチエイリアス効果については各自で確認してくだい.
|
定数名 |
機能・補間アルゴリズム |
InterpolationModeInvalid |
指定は無効 |
InterpolationModeDefault |
既定のモード.InterpolationModeBilinear |
InterpolationModeLowQuality |
低品質補間 |
InterpolationModeHighQuality |
高品質補間 |
InterpolationModeBilinear |
双一次補間.バイリニア法
50% 以下にする縮小処理には適していない |
InterpolationModeBicubic |
双三次補間.バイキュービック法
25% 以下にする縮小処理には適していない |
InterpolationModeNearestNeighbor |
最近傍補間.ニアレストネイバー法 |
InterpolationModeHighQualityBilinear |
高品質双一次補間 |
InterpolationModeHighQualityBicubic |
高品質双三次補間 |
|
図1
設計時画面
|
|
図2
InterpolationModeInvalid
- 上の画像は,VCL での描画結果
- 補間モードが無効な場合の結果
- GDI+ では,直線もそうであるが,ある程度の補間処理をするようだ
|
|
図3
InterpolationModeNearestNeighbor
- VCL での結果に近い
- VCL ではこのモードで内部処理しているのかも知れない
|
|
図4
InterpolationModeHighQualityBicubic
|
リスト1
GDI+ の TGPGraphics の補間モードのテスト |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, GDIPAPI, GDIPOBJ, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
Image2: TImage;
RadioGroup1: TRadioGroup;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure RadioGroup1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Self.Caption := 'GDI+ 画像拡大時の補間モード';
//TInterpolationModeの値は上から-1, 0, 1, 2, ...となっている
with RadioGroup1.Items do begin
Add('InterpolationModeInvalid');
Add('InterpolationModeDefault');
Add('InterpolationModeLowQuality');
Add('InterpolationModeHighQuality');
Add('InterpolationModeBilinear');
Add('InterpolationModeBicubic');
Add('InterpolationModeNearestNeighbor');
Add('InterpolationModeHighQualityBilinear');
Add('InterpolationModeHighQualityBicubic');
end;
RadioGroup1.ItemIndex := 0;
end;
//=============================================================================
// RadioGroup1のOnClickイベント
//=============================================================================
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
Button1Click(nil);
end;
//=============================================================================
// 画像を拡大・縮小する時の補間アルゴリズムの比較テスト
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LFilePath : string;
LBitmap : TBitmap;
LSrcRect : TRect;
LGDIGraphic : TGPGraphics;
LGDIBitmap : TGPBitmap;
LPolaMode : TInterpolationMode;
begin
//表示する画像のファイル名
LFilePath := '501.bmp';
//まずVCLのTCanvasのCopyRectによる描画の場合
LBitmap := TBitmap.Create;
try
LBitmap.LoadFromFile(LFilePath);
//元の画像のこの部分を拡大表示する
LSrcRect := Rect(20, 30, 20 + 35, 30 + 30);
//画像の一部をImage1に描画
Image1.Canvas.CopyRect(Rect(0, 0, Image1.Width, Image1.Height),
LBitmap.Canvas,
LSrcRect);
finally
FreeAndNil(LBitmap);
end;
//以下GDI+ の補間モードを指定しての描画
//RadioGruupのItemに応じて補間モードを選択
LPolaMode := -1;
case RadioGroup1.ItemIndex of
0: LPolaMode := InterpolationModeInvalid;
1: LPolaMode := InterpolationModeDefault;
2: LPolaMode := InterpolationModeLowQuality;
3: LPolaMode := InterpolationModeHighQuality;
4: LPolaMode := InterpolationModeBilinear;
5: LPolaMode := InterpolationModeBicubic;
6: LPolaMode := InterpolationModeNearestNeighbor;
7: LPolaMode := InterpolationModeHighQualityBilinear;
8: LPolaMode := InterpolationModeHighQualityBicubic;
end;
//Image2の画像を消去
Image2.Picture.Assign(nil);
LGDIGraphic := TGPGraphics.Create(Image2.Canvas.Handle);
LGDIBitmap := TGPBitmap.Create(LFilePath);
//補間モード設定
LGDIGraphic.SetInterpolationMode(LPolaMode);
//GDIBitmapをImage2に描画
//TCanvasのStretchDrawまたはCopyRectに相当する
LGDIGraphic.DrawImage(
LGDIBitmap,
MakeRect(0, 0, Image2.Width, Image2.Height),
LSrcRect.Left,
LSrcRect.Top,
LSrcRect.Right - LSrcRect.Left,
LSrcRect.Bottom - LSrcRect.Top,
UnitPixel);
LGDIBitmap.Free;
LGDIGraphic.Free;
end;
end.
上のサンプルで使用している画像は,下図のビットマップ画像です.この画像の一部分を拡大表示しています. |
|
図5
テストに使用したビットマップ画像 |
GDI+ の DrawImage には,多くのオーバーロード関数があります.
表示元の画像の領域を指定し,出力先の描画領域も指定可能な関数もあります.これを使用すると,元の画像をリサイズして拡大・縮小表示したりできます.また,元の画像の一部分だけをリサイズして拡大・縮小表示することもできます.
詳しくは,下記の参考リンクや,GDI+ のソースコードで確認してください. |
03_画像拡大時における終端ピクセル処理とピクセルオフセットの設定 |
TGPGraphics の SetInterpolationMode 関数を使用したアンチエイリアス処理は,直線や曲線の描画に対しても有効です.画像の拡大表示の場合,補間処理として別の要素があります.
画像の拡大では,周辺のピクセルの情報から新しいピクセルを追加作成します.この時,画像の上端と下端あるいは左端と右端のピクセルは,その下または右には参照すべきピクセルがありません.それをどう扱うかを TGPImageAttributes.SetWrapMode で指定することができます.また,ピクセルのどの領域までを参照するかを TGPGraphics.SetPixelOffsetMode で指定できます.
本サンプルは,[画像の表示と表示サイズでの画像保存]
の TImage への画像表示のサンプルプログラムにチェックボックスを追加し,現象と関数の効果を確認しやすいように,背景にテクスチャ画像を描画しています.
テストに使用した画像はビットマップ画像です.これらの処理がないと,終端のピクセルに,元の画像にな存在しない色のピクセルが追加されたり,均等に拡大されないことがあります.
下図の結果で示すような現象は画像の場合です.図形を描画するコードを Paint メソッド内等で実行する場合は発生しません.また,写真等の画像ではこの現象が発生してもあまり目立ちません.
|
|
図6
テストに使用したビットマップ画像
|
|
図7
処理をしないで拡大リサイズした結果
- SetWrapMode と SetPixelOffsetMode による処理をしない場合
- 画像の下端と右端に,元の画像にはない描画が行われている
|
|
図8
SetPixelOffsetMode だけの処理をした場合 |
|
図9
SetWrapMode と SetPixelOffsetMode による処理をした場合 |
下図は別のビットマップ画像での結果です.このビットマップ画像は,1 ドットの黒い線で矩形を描画して作成したものです.
上で述べた処理を実行すると,線の太さが均等に拡大されていることが確認できます.ただし,線の部分のピクセルの色が全て元の「黒」ではなく,中間色で補間されていいます.つまりぼやけた感じの描画となります. |
|
図10
テストに使用した別のビットマップ画像
|
|
図11
処理をしないで拡大表示した結果
- SetWrapMode と SetPixelOffsetMode による処理をしない場合
- 線の太さが均等に拡大されていない
- 下端と右端の描画は半透明
|
|
図12
処理をして拡大表示した結果
- SetWrapMode と SetPixelOffsetMode による処理をした場合
- 線の太さが均等に拡大されている
- ただし,線の部分の全てが元の「黒」ではない
|
リスト2
画像拡大時における終端のピクセル処理とピクセルオフセットの設定 |
//=============================================================================
// TCheckBoxのOnClickイベント処理
// 画像描画時の終端ピクセルの描画モードとピクセルのオフセットモードを設定
//=============================================================================
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
if not Assigned(FGPBitmap) then exit;
if FGPBitmap.GetWidth <= 0 then exit;
Image1.Picture.Assign(nil);
GDIDrawImageToTImage;
end;
//-----------------------------------------------------------------------------
// 実際の描画コード
//-----------------------------------------------------------------------------
procedure TForm1.GDIDrawImageToTImage;
var
LGPGraphic : TGPGraphics;
LBackImage : string;
LGPImage : TGPImage;
LGPTBrush : TGPTextureBrush;
begin
if not Assigned(FGPBitmap) then exit;
//TGPGraphicsのオブジェクトを生成
//描画先はこのTImageのCanvas
LGPGraphic := TGPGraphics.Create(Image1.Canvas.Handle);
//背景のテクスチャを作成して描画
LBackImage := ExpandFileName('backTexture.gif');
if FileExists(LBackImage) then begin
LGPImage := TGPImage.Create(LBackImage);
LGPTBrush := TGPTextureBrush.Create(LGPImage);
try
LGPGraphic.FillRectangle(LGPTBrush,
MakeRect(0, 0, Image1.Width,Image1.Height));
finally
FreeAndNil(LGPImage);
FreeAndNil(LGPTBrush);
end;
end;
//終端ピクセルの描画モードとピクセルのオフセットモードを設定
if CheckBox1.Checked then begin
//TGPImageAttributesによる設定が他にもあるかも知れない
//それらを有効するには生成していない場合に限って生成する方が良い
if not Assigned(FGPImageAttr) then begin
FGPImageAttr := TGPImageAttributes.Create;
end;
FGPImageAttr.SetWrapMode(WrapModeTileFlipXY);
end else begin
if Assigned(FGPImageAttr) then FreeAndNil(FGPImageAttr);
end;
if CheckBox2.Checked then begin
LGPGraphic.SetPixelOffsetMode(PixelOffsetModeHalf);
end;
//TGPBitmapをこのTImageのCanvasに描画
LGPGraphic.DrawImage(
FGPBitmap,
MakeRect(0, 0, Image1.Width, Image1.Height),
0,
0,
FGPBitmap.GetWidth,
FGPBitmap.GetHeight,
UnitPixel,
fGPImageAttr);
//Createしたオブジェクトは解放処理する
if Assigned(LGPGraphic) then FreeAndNil(LGPGraphic);
end;
本ページに限らず,GDI+ 関係のサンプルで「拡大」という用語を使用しています.これは実際にはリサイズの結果としての「拡大」を意味しています.
下図は 32 x 32 のサイズのアイコン画像を拡大表示した状態です.このような拡大表示は画像の画素,ピクセルの様子を見る時にも使われることがあります.Windows に付属の拡大鏡も画像を拡大表示するものです.
GDI+ では,画像のサイズよりも大きい Canvas に描画すると,下の一番最後の結果のように,アンチエイリアスの処理が行われます.
VCL の TCanvas.StretchDraw メソッドで画像を描画する時はアンチエイリアス処理は行われません,下の最初とその次のような結果となります.これは最近傍補間 (ニアレストネイバー法) による描画となります.GDI+ でもこの補間による描画はできますが,完全にアンチエイリアスなしの描画は行われないようです.
|
|
図13
画像の拡大表示の例
|
|
図14
Windows 7 に付属の拡大鏡による画像の拡大表示
- ディスクに保存してある画は,Windows フォトビューアで拡大表示すれば確認できる
|
|
図15
画像のリサイズによる拡大の例
|
05_GDI+ を使用しない画像の拡大 / 縮小時の補間 - Graphics32 |
VCL の TBitmap は,拡大または縮小の時に補間モードを指定できまん.
以下の GitHub のページからダウンロードしたユニットを使用すると,補間モードを指定して TBitmap 画像を拡大または縮小することができます.
|
[備考 1]
2022年10月28日現在,上のリンクからダウンロードした ZIP 書庫内のユニットresizeimageunit.pas の uses 部にある optimizedscanlineunit.pas, misc_functions.pas が ZIP 書庫に含まれていません.これらのユニットファイルの入手方法については不明です. |
上のリンクからダウンロードした ZIP 書庫は,ファイルが不足していて利用できません.そこで,Graphics32 を使用したサンプルを作成してみました.
Graphics32 の TBitmap32 クラスは,GDI+ と違い,TBitmap のアルファチャンネルも自動で処理してくれます.本サンプルでは,アルファチャンネル付きのビットマップ画像を使用しています.TBitmap32 を使用する部分は,独立したメソッドとして実装しました.補間モードは,バイリニアニ固定しています. |
|
図16
添付の画像を拡大表示
- 左が元の画像
- 背景の市松模様の画像は,
透過状態の確認用
|
リスト3
Graphics32 を使用して TBitmap 画像をリサイズ |
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
Image2: TImage;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
procedure ResizeBmpByGR32(SrcBmp: TBitmap; DstBmp: TBitmap;
DstWidht, DstHeight: Integer; ResizeFlag: Boolean = True); overload;
procedure ResizeBmpByGR32(SrcBmp: TBitmap; DstBmp: TBitmap; SrcX, SrcY, SrcCX,
SrcCY: Integer; DstCX, DstCY: Integer; ResizeFlag: Boolean = True); overload;
procedure DrawBackGroundImage(ACanvas: TCanvas; AFilePath: string);
end;
var
Form1: TForm1;
implementation
uses
GR32,
GR32_Resamplers;
{$R *.dfm}
//=============================================================================
// TBitmap の画像をリサイズ
// TBitmap 以外の画像も TBitmap に変換すれば同様ににリサイズ可能
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LSrcBmp : TBitmap;
LDstBmp : TBitmap;
begin
LSrcBmp := TBitmap.Create;
LDstBmp := TBitmap.Create;
try
LSrcBmp.AlphaFormat := afDefined;
LSrcBmp.LoadFromFile('virus detected.bmp');
// リサイズ前の TBitmap を TImage に描画
DrawBackGroundImage(Image1.Canvas, 'backTexture_02.bmp');
Image1.Canvas.Draw(0, 0, LSrcBmp);
// 256 x 256 にリサイズ
ResizeBmpByGR32(LSrcBmp, LDstBmp,256, 256);
// リサイズ後の TBitmap を TImage に描画
DrawBackGroundImage(Image2.Canvas, 'backTexture_02.bmp');
Image2.Canvas.Draw(0, 0, LDstBmp);
finally
FreeAndNil(LSrcBmp);
FreeAndNil(LDstBmp);
end;
end;
//-----------------------------------------------------------------------------
// Graphics32 を使用した TBitmap 画像のリサイズ
//-----------------------------------------------------------------------------
procedure TForm1.ResizeBmpByGR32(SrcBmp, DstBmp: TBitmap; DstWidht,
DstHeight: Integer; ResizeFlag: Boolean);
begin
ResizeBmpByGR32(SrcBmp, DstBmp, 0, 0,
SrcBmp.Width, SrcBmp.Height, DstWidht, DstHeight, ResizeFlag);
end;
//-----------------------------------------------------------------------------
// Graphics32 を使用した TBitmap 画像のリサイズ
// 元の TBitmap の部分的な矩形領域の拡大 / 縮小も可能
// 補間モードは TLinearResampler ( 多分,双一次補間 - バイリニア補間 ) に固定
//
// uses に GR32, GR32_Resamplers が必要
//-----------------------------------------------------------------------------
procedure TForm1.ResizeBmpByGR32(SrcBmp, DstBmp: TBitmap; SrcX, SrcY, SrcCX,
SrcCY, DstCX, DstCY: Integer; ResizeFlag: Boolean);
var
LPixelFmt : TPixelFormat;
LAlphaFmt : TAlphaFormat;
LSrcBmp32 : TBitmap32;
LDstBmp32 : TBitmap32;
LSrcRect : TRect;
LDstRect : TRect;
begin
LPixelFmt := SrcBmp.PixelFormat;
LAlphaFmt := SrcBmp.AlphaFormat;
// 操作対象の画像の矩形領域
LSrcRect := Rect(SrcX, SrcY, SrcCX, SrcCY);
LDstRect := Rect(0,0, DstCX, DstCY);
LSrcBmp32 := TBitmap32.Create;
LDstBmp32 := TBitmap32.Create;
try
if ResizeFlag then begin
LSrcBmp32.Resampler := TLinearResampler.Create;
end;
// 元の TBitmap を TBitmap32 に変換
SrcBmp.AlphaFormat := LAlphaFmt;
LSrcBmp32.Assign(SrcBmp);
// TBitmap32 を変換後のサイズにして,その Canvas に元のビットマップを描画 L
LDstBmp32.SetSize(LDstRect.Width, LDstRect.Height);
LDstBmp32.Draw(LDstRect, LSrcRect, LSrcBmp32);
// リサイズ後に画像を描画した TBitmap32 を TBitmap に変換
DstBmp.Assign(LDstBmp32);
DstBmp.AlphaFormat := LAlphaFmt;
// ビット深さを元に戻す
DstBmp.PixelFormat := LPixelFmt;
finally
FreeAndNil(LSrcBmp32);
FreeAndNil(LDstBmp32);
end;
end;
//----------------------------------------------------------------------------
// TImage の背景として市松模様のブラシを描画
// TBitmap の透過状態の確認用
// この模様が見える部分は透明または半透明の部分ということになる
//----------------------------------------------------------------------------
procedure TForm1.DrawBackGroundImage(ACanvas: TCanvas; AFilePath: string);
var
LBmpBack : TBitmap;
begin
LBmpBack := TBitmap.Create;
try
LBmpBack.LoadFromFile(AFilePath);
ACanvas.Brush.Style := bsSolid;
ACanvas.Brush.Bitmap := LBmpBack;
ACanvas.FillRect(ACanvas.ClipRect);
finally
FreeAndNil(LBmpBack);
end;
end;
end.
補間モードの設定コードを次のようにすれば,任意の補間モードにできます. |
// 別の補間モードにするには TLanczosKernel の部分を変更する
// LResamplerType : TKernelResampler;
if ResizeFlag then begin
LResamplerType := TKernelResampler.Create(LSrcBmp32);
LResamplerType.Kernel := TLanczosKernel.Create;
LResamplerType.Changed;
LSrcBmp32.Resampler := LResamplerType;
end;
補間によるアンチエイリアスの効果を,直線を描画しただけのビットマップ画像で確認した結果です. |
|
図17
アンチエイリアスなし
- TCanvas.StretchDraw による描画
|
|
図18
アンチエイリアスの効果
|
テスト用の,直線だけのビットマップ画像は,以下のコードで作成しました.このビットマップを保存して拡大表示しました.拡大表示した画像をピクセル単位で拡大したのが上の画像です. |
procedure TForm1.Button1Click(Sender: TObject);
const
FBackColor : TColor = clWhite;
var
LBitmap : TBitmap;
LCanvas : TCanvas;
begin
LBitmap := TBitmap.Create;
try
LBitmap.SetSize(32, 32);
LBitmap.PixelFormat := pf24bit;
LCanvas := LBitmap.Canvas;
LCanvas.Brush.Color := FBackColor;
LCanvas.FillRect(LCanvas.ClipRect);
LCanvas.Pen.Width := 5;
LCanvas.Pen.Color := clBlack;
LCanvas.MoveTo(0, 0);
LCanvas.LineTo(LBitmap.Width, LBitmap.Height);
LBitmap.SaveToFile('line.bmp');
finally
FreeAndNil(LBitmap);
end;
end;
[備考 2]
今回作成したサンプルは,Graphics32 の [Source] フォルダにライブラリパスを通すだけでコンパイルして実行できます.
Graphics32 には,TPaintBox32, TImage32, TBitmap32List などのコンポーネントも含まれています.それらを利用するには,[Source] 内の GR32_Reg.pas をインストールします.参考リンクの Graphics32 のリンクからダウンロードしたファイルにはパッケージファイルはありません.適当なパッケージに登録します. |
|
図19
Graphics32 関係コンポーネント |
Delphi XE5 で,Graphics32 を使用するプロジェクトをビルド (再構築) すると,「Windows.dcu が見つかりません」などのエラーが発生します.その場合は,以下のように,ユニットスコープ名 WinApi を追加すればエラーは発生しなくなります.
こエラーの発生は,数十ヵ所あります. |
Windows, Messages ---> Winapi.Windows, Winapi.Messages
Windows.TPoint ---> Winapi.Windows.TPoint;
等々
Graphics32 の TImage32 に,TBitmap32 のビットマップ画像を描画する例です. |
|
図20
実行結果 |
リスト4
Graphics32 の TImage32 に,TBitmap32 のビットマップ画像を描画 |
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtDlgs, Vcl.StdCtrls,
Vcl.ExtCtrls, GR32, GR32_Image, GR32_Backends;
type
TForm1 = class(TForm)
Button1: TButton;
Image321: TImage32;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// Graphics32 の TImage32 に TBitmap32 を描画する例
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LBitmap32 : TBitmap32;
LBitmap : TBitmap;
begin
LBitmap32 := TBitmap32.Create;
try
// TImage32.Bitmmap ( TImage の内部ピッマップ相当) のサイズを設定
Image321.Bitmap.SetSize(Image321.Width, Image321.Height);
// 背景を指定色で塗り潰す
// Ex. 緑は clGreen32
Image321.Bitmap.Clear($FFFFFFFF);
// TImage32 の背景を市松模様のタイルにする
LBitmap := TBitmap.Create;
try
LBitmap.LoadFromFile('backTexture_02.bmp');
Image321.Bitmap.Canvas.Brush.Style := bsSolid;
Image321.Bitmap.Canvas.Brush.Bitmap := LBitmap;
Image321.Bitmap.Canvas.FillRect(Image321.Bitmap.Canvas.ClipRect);
finally
FreeAndNil(LBitmap);
end;
// ビットマップ画像を読み込んで TImage32 ( の TBitmap ) に描画
LBitmap32.LoadFromFile('virus detected.bmp');
// dmTransparent にすると半透明は無効 ( RGB 値だけで描画される )
LBitmap32.DrawMode := dmBlend;
LBitmap32.DrawTo(Image321.Bitmap);
finally
FreeAndNil(LBitmap32);
end;
end;
end.
|