年初,我写了一篇关于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.
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后的图像: