GDI+ ColorMatrix的完全揭秘与代码实现(下)
2008-09-09 19:25:20 来源:WEB开发网上面有2个ColorMatrix处理过程,第一个可以直接对GDI+ Bitmap图像作处理(GDI+自身的ColorMatrix功能只能显示);第二个则是不改变GDI+图像本身,只是根据ColorMatrix的数据对所有GDI+ Image进行显示。
下面是一个GDI+图像测试代码,该测试代码与《GDI+ for VCL基础 -- 颜色调整矩阵ColorMatrix详解》是差不多的,只是把原先由GDI+ ImageAttributes处理改为上面的GdipColorMatrixDraw过程处理。有兴趣的朋友可以同《GDI+ for VCL基础 -- 颜色调整矩阵ColorMatrix详解》的测试代码作一下比较。
unit main1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Gdiplus, ExtCtrls, StdCtrls, Buttons, Grids;
type
TMainForm = class(TForm)
Label1: TLabel;
PaintBox1: TPaintBox;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
SpeedButton4: TSpeedButton;
StringGrid1: TStringGrid;
BitBtn1: TBitBtn;
BitBtn3: TBitBtn;
BitBtn2: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure StringGrid1GetEditText(Sender: TObject; ACol, ARow: Integer;
var Value: String);
procedure PaintBox1Paint(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton4Click(Sender: TObject);
procedure SpeedButton3Click(Sender: TObject);
private
{ Private declarations }
Matrix: TColorMatrix;
Image: TGpImage;
procedure SetMatrix;
procedure GetMatrix;
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
uses Math, GpBmpUtils;
{$R *.dfm}
const
ColorMatrix: TColorMatrix =
(
(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.0, 0.0, 0.0, 0.0, 1.0)
);
procedure TMainForm.GetMatrix;
var
i, j: Integer;
begin
for i := 0 to 4 do
for j := 0 to 4 do
Matrix[i, j] := StrToFloat(StringGrid1.Cells[j, i]);
end;
procedure TMainForm.SetMatrix;
var
i, j: Integer;
begin
for i := 0 to 4 do
for j := 0 to 4 do
StringGrid1.Cells[j, i] := Format('%.2f', [Matrix[i, j]]);
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
Image := TGpImage.Create('....Media100_0349.jpg');
BitBtn2.Click;
end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
Image.Free;
end;
// 灰度化
procedure TMainForm.SpeedButton1Click(Sender: TObject);
var
I: Integer;
begin
Move(ColorMatrix, Matrix, Sizeof(Matrix));
for I := 0 to 2 do
begin
Matrix[0, I] := 0.3;
Matrix[1, I] := 0.59;
Matrix[2, I] := 0.11;
end;
SetMatrix;
PaintBox1.Invalidate;
end;
// 调整亮度0.1(25.5)
procedure TMainForm.SpeedButton2Click(Sender: TObject);
var
I: Integer;
begin
Move(ColorMatrix, Matrix, Sizeof(Matrix));
for I := 0 to 2 do
Matrix[4, I] := 0.1;
SetMatrix;
PaintBox1.Invalidate;
end;
// 反色
procedure TMainForm.SpeedButton3Click(Sender: TObject);
begin
Move(ColorMatrix, Matrix, Sizeof(Matrix));
Matrix[0, 0] := -1;
Matrix[1, 1] := -1;
Matrix[2, 2] := -1;
SetMatrix;
PaintBox1.Invalidate;
end;
// 半透明显示
procedure TMainForm.SpeedButton4Click(Sender: TObject);
begin
Move(ColorMatrix, Matrix, Sizeof(Matrix));
Matrix[3, 3] := 0.5;
SetMatrix;
PaintBox1.Invalidate;
end;
procedure TMainForm.StringGrid1DrawCell(Sender: TObject; ACol,
ARow: Integer; Rect: TRect; State: TGridDrawState);
var
r: TRect;
Text: string;
x: Integer;
begin
with StringGrid1 do
begin
Text := Cells[ACol, ARow];
if Text = '' then Text := '0.00'
else
begin
x := Pos('.', Text);
if x < 1 then Text := Text + '.00'
else if x = 1 then Text := '0' + Text;
end;
r := TRect(Rect);
Canvas.FillRect(r);
Canvas.Pen.Color := clBtnShadow;
Canvas.Rectangle(r);
InflateRect(r, -2, -2);
DrawText(Canvas.Handle, PChar(Text), Length(Text), r, DT_RIGHT);
end;
end;
procedure TMainForm.StringGrid1GetEditText(Sender: TObject; ACol,
ARow: Integer; var Value: String);
var
v: Double;
begin
if Value = '' then v := 0.0
else v := StrToFloat(Value);
Value := Format('%.2f', [v]);
end;
procedure TMainForm.PaintBox1Paint(Sender: TObject);
var
g : TGpGraphics;
begin
g := TGpGraphics.Create(PaintBox1.Canvas.Handle);
g.FillRectangle(Brushs.White, GpRect(PaintBox1.ClientRect));
try
g.TranslateTransform(10, 10);
g.DrawImage(Image, 0, 0, Image.Width, Image.Height);
g.TranslateTransform(Image.Width + 10, 0);
// 使用自己写的ColorMatrix转换
GdipColorMatrixDraw(g, 0, 0, Image, Matrix);
finally
g.Free;
end;
end;
procedure TMainForm.BitBtn1Click(Sender: TObject);
begin
GetMatrix;
SetMatrix;
PaintBox1.Invalidate;
end;
procedure TMainForm.BitBtn2Click(Sender: TObject);
begin
Move(ColorMatrix, Matrix, Sizeof(Matrix));
SetMatrix;
PaintBox1.Invalidate;
end;
end.
同样也贴上个运行效果图:
该效果图是个处理-1矩阵实现图像取反的画面,仔细观察右边的取反图,不难发现其中有不少黑色的点,尤其是画面右上角“圣亚”2个字下面,更是出现一些难看的色斑,这些问题在《GDI+ ColorMatrix的完全揭秘与代码实现(上)》中已经作了详细的解说。其实这个问题完全可以进行改进,但本文的目的是揭秘和完整实现,改进后,一些非主要效果肯定会与“正版”不一样。^_^
代码中所用Gdiplus单元下载地址及BUG更正见文章《GDI+ for VCL基础 -- GDI+ 与 VCL》。建议和指导请来信:maozefa@hotmail.com
Tags:GDI ColorMatrix 完全
编辑录入:爽爽 [复制链接] [打 印]更多精彩
赞助商链接