255 - (255 - g) * (255 - 0) div 255, // 计算 g 值
255 - (255 - b) * (255 - 0) div 255); // 计算 b 值
end;
end;
rect.left := 448;
rect.top := 152;
rect.right := rect.left + png.width;
rect.bottom := rect.top + png.height;
png.draw(canvas, rect);
t2 := gettickcount - t1;
showmessage(inttostr(t2));
png.free;
end;
颜色转换后的效果如图3。
目标看似达到了,不过看看这粗糙的算法吧,二重循环遍历每个象素一定是很慢的,测试了一下转换这张200*200(象素)的图片在p4 2.4的cpu下耗时平均94ms(上面我用了一个rgbtemp临时变量来保存当前像素的rgb值,要不然在计算r、g、b时分别去直接读png.pixels[i,j]的话时间基本要再翻倍)。天!这个耗时很可观哪!后来我把代码改成把图片的scanline属性复制到一个指针数组,大大提高了运算速度:
{ 定义指针数组类型 }
const
maxpixelcount = 65536;
type
prgbarray = ^trgbarray;
trgbarray = array [0..maxpixelcount - 1] of trgbtriple;
procedure tform1.button3click(sender: tobject);
var
i, j: integer;
row: prgbarray;
png: tpngobject;
rect: trect;
begin
png := tpngobject.create;
png.loadfromfile('2.png');
for i := 0 to png.height - 1 do
begin
row := png.scanline[i]; // 复制scanline属性到row指针数组
for j := 0 to png.width - 1 do
begin
row[j].rgbtred := 255 - (255 - row[j].rgbtred) * (255 - 153) div 255;
row[j].rgbtgreen := 255 - (255 - row[j].rgbtgreen) * (255 - 0) div 255;
row[j].rgbtblue := 255 - (255 - row[j].rgbtblue) * (255 - 0) div 255;
end;
end;
{ ... }
{ 后面的画图片代码相同 }
经过这个算法优化,运行时间缩短到几乎为0ms了(偶尔出现16ms)!
< 收工 >
总算写完了^^。以上算法是我自己琢磨出来的,网上也没找到什么相关资料,哪位朋友如果有更好的方法,请多多指点,也希望能和我联系(islet8@yahoo.com.cn)。希望这篇文章能给各位朋友起到抛砖引玉的作用!
以上代码在winxp + delphi7下调试通过。