分享
 
 
 

获取TBitMap图像缓冲区,提高图像处理速度

王朝delphi·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

使用Dephi进行图像处理可以有多种方法,最常用的应该算是TBitmap,它提供方便的图像存取能力,结合Canvas可进行画线、画圆、图像拷贝等操作。不过在进行大量的图像处理操作时,为了获得更高的速度,我们希望能够直接对图像缓冲区进行读写。查阅Dephi的帮助手册没有发现直接取得整个图像缓冲区的功能,但提供的ScanLine属性可以取得指定行图像数据的指针,比较接近我们的要求,先看看ScanLine的描述:

Provides indexed access to each line of pixels.

property ScanLine[Row: Integer]: Pointer;

Description

ScanLine is used only with DIBs (Device Independent Bitmaps) for image editing tools that do low-level pixel work.

让我们再看看ScanLine[0]、ScanLine[1]的关系:

procedure TForm1.Button1Click(Sender: TObject);

var

BitMap: TBitmap;

S: String;

begin

BitMap := TBitmap.Create;

try

BitMap.PixelFormat := pf24bit; //24位色,每像素点3个字节

BitMap.Width := 1000;

BitMap.Height := 2;

FmtStr(S, 'ScanLine[0]:%8x'#13'ScanLine[1]:%8x'#13'ScanLine[1]-ScanLine[0]:%d'

, [Integer(BitMap.ScanLine[0]), Integer(BitMap.ScanLine[1])

, Integer(BitMap.ScanLine[1]) - Integer(BitMap.ScanLine[0])]);

MessageBox(Handle, PChar(S), 'ScanLine', MB_OK);

finally

if Assigned(BitMap) then FreeAndNil(BitMap);

end;

end;

下面是运行结果:

ScanLine[0]: E90BB8

ScanLine[1]: E90000

ScanLine[1]-ScanLine[0]:-3000

前两个结果因机器不同而不同,第三个结果很特别,ScanLine[0]与ScanLine[1]之间相差3000=1000像素宽×3字节这很容易理解,但为什么是负数呢?因为BMP图像数据是“按行存放,每行按双字对齐,行按倒序方式存放”的,也就是说屏幕显示的第一行存放在最后,屏幕显示的最后一行存放在前面,所以用ACDSee等看图软件查看尺寸较大的位图时先从下部开始显示就是这个道理。

从上面的结果可以看出TBitmap的图像数据在内存中是按行倒序连续存放的,通过TBitmap.ScanLine[TBitmap.Height-1]可以取得首地址即图像缓冲区地址。接着我们来实践一下,通过直接对图像缓冲区的读写将图像淡出到黑色:

procedure TForm1.Button1Click(Sender: TObject);

const

FADEOUT_STEP = 24; //淡出衰减值

FIX_WIDTH = 320;

FIX_HEIGHT = 200;

var

BitMap: TBitmap;

hWinDC: HDC;

flagAgein: Boolean;

lpBuffer: PByte; //图像缓冲区指针

begin

BitMap := TBitmap.Create;

if not Assigned(BitMap) then Exit;

try

//设置位图格式、宽度、高度

BitMap.PixelFormat := pf24bit;

BitMap.Width := FIX_WIDTH;

BitMap.Height := FIX_HEIGHT;

//设置Form的宽充、高度,便于显示结果

Button1.Visible := false;

ClientWidth := FIX_WIDTH;

ClientHeight := FIX_HEIGHT;

//拷贝图像到Bitmap中

hWinDC := GetDC(0);

if (hWinDC<>NULL) then BitBlt(Bitmap.Canvas.Handle, 0, 0, FIX_WIDTH, FIX_HEIGHT, hWinDC, 0, 0, SRCCOPY)

else BitBlt(Bitmap.Canvas.Handle, 0, 0, FIX_WIDTH, FIX_HEIGHT, Canvas.Handle, 0, 0, SRCCOPY);

repeat

flagAgein := false;

lpBuffer := BitMap.ScanLine[FIX_HEIGHT-1]; //取得图像缓冲区首地址

//Integer(BitMap.ScanLine[0]) + FIX_WIDTH*3 为图像缓冲区结束地址

while Integer(lpBuffer) < Integer(BitMap.ScanLine[0]) + FIX_WIDTH*3 do begin

if lpBuffer^>FADEOUT_STEP then

begin

Dec(lpBuffer^, FADEOUT_STEP);

flagAgein := true;

end

else lpBuffer^ :=0;

Inc(lpBuffer);

Application.ProcessMessages;

end;

Canvas.Draw(0, 0, BitMap);

until (not flagAgein);

MessageBox(Handle, 'Done', 'Fadeout', MB_OK);

finally

if Assigned(BitMap) then FreeAndNil(BitMap);

Button1.Visible := true;

end;

end;

最后补充说明一下:

1、Bitmap图像缓冲区是双节对齐的,如果把例1中的图像宽度改为999,一个像素行还是占3000个字节。

2、目前Bitmap.PixelFormat有pfDevice、pf1bit、pf4bit、pf8bit、pf15bit、pf16bit、pf24bit、pf32bit、pfCustom共9种,不同格式每个像素所占字节数不同,其中pf4bit和pf8bit格式的图像缓冲区保存的为颜色索引号,真正的颜色值在调色板中,pf15bit、pf16bit格式中RGB所占的位数(Bit)不一定是等长的。有兴趣的可查阅相关资料。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有