GDI+ ColorMatrix的完全揭秘与代码实现(下)
2008-09-09 19:25:20 来源:WEB开发网二、ColorMatrix功能的代码实现。
本文在《GDI+ ColorMatrix的完全揭秘与代码实现(上)》的ColorMatrix原理揭秘的基础上,用代码来完整的实现GDI+的ColorMatrix功能。GDI+中设置ColorMatrix时有2个枚举选项,在实际运用中极少使用,所以代码中以GDI+设置ColorMatrix的缺省方式实现。
先贴上通用数据定义:
type
// 与GDI+ TBitmapData结构兼容的图像数据结构
TImageData = packed record
Width: LongWord; // 图像宽度
Height: LongWord; // 图像高度
Stride: LongWord; // 图像扫描线字节长度
PixelFormat: LongWord; // 未使用
Scan0: Pointer; // 图像数据地址
Reserved: LongWord; // 保留
end;
PImageData = ^TImageData;
该数据类型是方便Delphi的TBitmap而定义的,如果不准备兼容TBitmap,可以用TBitmapData来替换它。为了方便阅读,同时能使过程代码发挥较高的效率,本文提供了2个版本,下面是一个纯PAS的浮点数ColorMatrix实现代码:
procedure SetColorMatrixF(Data: TImageData; Matrix: TColorMatrix);
var
I, J, Count: Integer;
P: PRGBQuad;
MainValue: Boolean;
v: Integer;
procedure SetPixel;
var
Pixel: array[0..3] of Byte;
I, J: Integer;
ps: PByteArray;
begin
ps := Pointer(P);
// 注意:为使矩阵与ARGB排列顺序一致,以下运算中调整了行列的顺序
for I := 0 to 3 do
begin
if I < 3 then
J := 2 - I
else
J := I;
// 如果只存在主对角线数据,只处理颜色缩放
if MainValue then
Pixel[J] := Round(Matrix[I, I] * ps[J])
// 否则,处理所有颜色变换
else
Pixel[J] := Max(0, Min(255, Round(Matrix[0, I] * ps[2] +
Matrix[1, I] * ps[1] +
Matrix[2, I] * ps[0] +
Matrix[3, I] * ps[3] +
Matrix[4, I] * 255)));
end;
for I := 0 to 3 do
ps[I] := Pixel[I];
end;
begin
// 处理矩阵中大与255的值(取模),并判断主对角线外是否存在数据
MainValue := True;
for I := 0 to 4 do
for J := 0 to 4 do
begin
v := Round(Matrix[I, J]) div 256;
if v > 0 then
Matrix[I, J] := Matrix[I, J] - 256.0 * v;
if (I <> J) and (Matrix[I, J] <> 0) then
MainValue := False;
end;
Count := Data.Width * Data.Height;
P := Data.Scan0;
for I := 1 to Count do
begin
SetPixel;
Inc(P);
end;
end;
Tags:GDI ColorMatrix 完全
编辑录入:爽爽 [复制链接] [打 印]赞助商链接