GDI+ 在Delphi程序的应用 -- 调整图像亮度
调整图像的亮度可以有很多方法,最常用的方法就是对图像像素点的R、G、B三个分量同时进行增加(减少)某个值,达到调整亮度的目的。我在这里使用GDI+图像的扫描线来处理,核心处理采用了2个相同的过程,一个是Pascal过程,一个是嵌入汇编过程,通过比较,对小的图像几乎没有什么区别,对比较大的图像处理还是有一定的区别(具体测试效果见代码中的注释),这说明Delphi的代码优化还是很好的。
使用GDI+图像的扫描线处理必须调用TGpBitmap.LockBits和TGpBitmap.UnLockBits过程,而这2个过程的调用相当耗时,以2304 *1728大小的图片为例,耗时竟达188毫秒!而亮度调整过程最长只耗时63毫秒。由此可以看出使用GDI+图像扫描线处理图像并非十分理想。
需要说明的是,本例子及以后GDI+ for Delphi例子的Gdiplus单元是本人自己写的,与目前网上流通的版本有一定的区别,浏览着需要测试例子,可作适当修改,或者发邮件向本人索取Gdiplus单元。
数据类型:
-
type
-
-
TImageData=packedrecord
-
Width:LongWord;
-
Height:LongWord;
-
Stride:LongWord;
-
PixelFormat:LongWord;
-
Scan0:Pointer;
-
Reserved:LongWord;
-
end;
- PImageData=^TImageData;
-
-
functionGetImageData(Bmp:TBitmap):TImageData;
-
begin
-
Bmp.PixelFormat:=pf32bit;
-
Result.Width:=Bmp.Width;
-
Result.Height:=Bmp.Height;
-
Result.Scan0:=Bmp.ScanLine[Bmp.Height-1];
-
Result.Stride:=Result.Widthshl2;
-
-
end;
过程代码:
-
-
procedureBrightness(Data:TImageData;Value:Integer);
-
asm
- pushesi
- pushedi
-
movedi,[eax+16]
-
movesi,[eax+4]
- imulesi,[eax]
- cld
- @PixelLoop:
-
movecx,3
- @RGBLoop:
- movzxeax,[edi]
- addeax,edx
-
jns@@1
-
xoreax,eax
-
jmp@@2
-
@@1:
-
cmpeax,255
-
jle@@2
-
moveax,255
-
@@2:
- stosb
- loop@RGBLoop
- incedi
- decesi
- jnz@PixelLoop
- popedi
- popesi
-
end;
-
-
procedureGdipBrightness(Bmp:TGpBitmap;Value:Integer);
-
var
- Data:TBitmapData;
-
begin
-
ifValue=0thenExit;
-
Data:=Bmp.LockBits(GpRect(0,0,Bmp.Width,Bmp.Height),[imRead,imWrite],pf32bppARGB);
-
try
- Brightness(TImageData(Data),Value);
-
finally
-
Bmp.UnlockBits(Data);
-
end;
-
end;
-
-
procedureBitmapBrightness(Bmp:TBitmap;Value:Integer);
-
begin
-
ifValue<>0then
- Brightness(GetImageData(Bmp),Value);
-
end;
测试代码:
-
-
-
procedureGdipBrightness_Pas(Bmp:TGpBitmap;Value:Integer);
-
functionSetRGBValue(Rgb:Byte):Integer;
-
begin
-
Result:=Value+Rgb;
-
ifResult<0then
-
Result:=0
-
elseifResult>255then
-
Result:=255;
-
end;
-
var
- Data:TBitmapData;
- P:PRGBQuad;
- I,Count:LongWord;
-
begin
-
ifValue=0thenExit;
-
Data:=Bmp.LockBits(GpRect(0,0,Bmp.Width,Bmp.Height),[imRead,imWrite],pf32bppARGB);
-
try
-
Count:=Data.Width*Data.Height;
-
P:=Data.Scan0;
-
forI:=1toCountdo
-
begin
- P^.rgbBlue:=SetRGBValue(P^.rgbBlue);
- P^.rgbGreen:=SetRGBValue(P^.rgbGreen);
- P^.rgbRed:=SetRGBValue(P^.rgbRed);
- Inc(P);
-
end;
-
finally
-
Bmp.UnlockBits(Data);
-
end;
-
end;
-
-
procedureTForm1.Button1Click(Sender:TObject);
-
var
- Image:TGpBitmap;
- g:TGpGraphics;
-
begin
-
Image:=TGpBitmap.Create('D:/VclLib/GdiplusDemo/Media/20041001.jpg');
-
g:=TGpGraphics.Create(Handle,False);
-
g.DrawImage(Image,10,10);
-
-
GdipBrightness(Image,30);
-
g.DrawImage(Image,10,220);
-
Image.Free;
-
g.Free;
-
end;
-
-
procedureTForm1.Button2Click(Sender:TObject);
-
var
- Image:TBitmap;
-
begin
-
Image:=TBitmap.Create;
-
Image.LoadFromFile('D:/VclLib/GdiplusDemo/Media/20041001.bmp');
-
Canvas.Draw(10,10,Image);
-
BitmapBrightness(Image,-30);
-
Canvas.Draw(10,220,Image);
-
Image.Free;
-
end;
分享到:
相关推荐
GDI+入门指导书------经典 非常适合于GDI+初学者
windwos C++ gdi++实现jpg图像压缩-图像裁剪和缩放-图像格式转换-图像dpi修改
——在GDI+ Painter应用程序中添加颜色、钢笔和画笔 总结 第5章 颜色、字体和文本 5.1 访问Graphics对象 5.2 使用颜色 5.3 使用字体 5.4 使用文本和字符串 5.5 渲染文本的质量和性能 5.6 高级版式 5.7 一个...
DELPHI版的GDI++库,内有Demos.
WINDOWS GDI和GDI+编程实例剖析. - READ
使用Delphi+GDI实现图片的镜像翻转,有需要的可以试试。
——在GDI+ Painter应用程序中添加颜色、钢笔和画笔 总结 第5章 颜色、字体和文本 5.1 访问Graphics对象 5.2 使用颜色 5.3 使用字体 5.4 使用文本和字符串 5.5 渲染文本的质量和性能 5.6 高级版式 5.7 一个...
使用GDI+进行图形缩放、拖动,多种图片格式支持,仅简单示例。 问题源贴:http://bbs.csdn.net/topics/390638094
GDI+程序设计.pdf,书籍和随书源码。
GDI+程序设计 GDI+程序设计 GDI+程序设计 GDI+程序设计
教你在VC下如何使用GDI+进行 图像程序设计,是整理的比较全的资料。
一本为C#开发人员准备的图形图像处理技术的书籍
在Delphi中使用GDI+,范例中包含GDI+各种效果的测试。
其中,ULONG_PTR是一个DWORD数据类型,该成员变量用来保存GDI+被初始化后在应用程序中的GDI+标识,以便能在应用程序退出后,引用该标识来调用Gdiplus:: GdiplusShutdown来关闭GDI+。 (2)在应用类中添加...
Delphi GDI+
一本不可多得的GDI+绘图书籍,网上GDI+介绍其实挺少的,研究GDI+绘图时,浪费了不少时间,找了很久,发现了一本好书,在万分激动的心情下,将此书分享给大家,希望在GDI+绘图上给您一些指导。
GDI+对话框的显示,里面有5个特效和打开文件的代码