年初,我寫了一篇關於GDI+亮度調整的文章,見《GDI+ 在Delphi程式的應用 -- 調整映像亮度》,採用的是掃描線逐點改變,當時有網友評論時提出是否可以ColorMatrix進行調整,我覺得映像像素值上下限不好控制,加之沒時間沒去研究,今天,我卻發現該網友提出的方案居然是切實可行的。改變映像亮度,實際就是對像素點的各顏色分量值作一個平移,使用ColorMatrix進行平移是個輕而易舉事!
在《GDI+ 在Delphi程式的應用 -- 調整映像亮度》一文舉例中對圖片增加亮度20,用ColorMatrix矩陣來說,就是個顏色值平移20 / 256 = 0.078,也就是各顏色分量值加0.078,用ColorNatrix矩陣表示為:
1.0 0.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0 0.0
0.0 0.0 1.0 0.0 0.0
0.0 0.0 0.0 1.0 0.0
0.078 0.078 0.078 0.0 1.0
重寫《GDI+ 在Delphi程式的應用 -- 調整映像亮度》中的例子:
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure Edit1Exit(Sender: TObject);
private
...{ Private declarations }
Value: Integer;
public
...{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses Gdiplus;
...{$R *.dfm}
procedure SetBrightness(Image: TGpImage; Value: Shortint);
var
Tmp: TGpImage;
attr: TGpImageAttributes;
g: TGpGraphics;
v: Single;
I: Integer;
ColorMatrix: TColorMatrix;
begin
Tmp := Image.Clone;
g := TGpGraphics.Create(Image);
attr := TGpImageAttributes.Create;
try
FillChar(ColorMatrix, 25 * Sizeof(Single), 0);
for I := 0 to 4 do
ColorMatrix[I][I] := 1.0; // 初始化ColorMatrix為單位矩陣
v := Value / 256; // 亮度調整絕對值轉換為相對值
for I := 0 to 2 do
ColorMatrix[4][I] := v; // 設定ColorMatrix各顏色分量行的虛擬位
attr.SetColorMatrix(ColorMatrix);
g.DrawImage(Tmp, GpRect(0, 0, Image.Width, Image.Height),
0, 0, Tmp.Width, Tmp.Height, utPixel, attr);
finally
g.Free;
attr.Free;
Tmp.Free;
end;
end;
procedure TForm1.Edit1Exit(Sender: TObject);
begin
if Edit1.Text = '' then
Text := '20';
Value := StrToInt(Edit1.Text);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Image: TGpImage;
g: TGpGraphics;
begin
Image := TGpImage.Create('..media41001.jpg');
g := TGpGraphics.Create(Handle, False);
g.DrawImage(Image, 10, 10);
SetBrightness(Image, Value);
g.DrawImage(Image, 200, 10);
g.Free;
image.Free;
end;
end.
運行結果,左邊為原圖,右邊為亮度加20後的映像: