用VB写高效的图像处理程序doc资料.docx

上传人:b****8 文档编号:29783746 上传时间:2023-07-26 格式:DOCX 页数:21 大小:27.64KB
下载 相关 举报
用VB写高效的图像处理程序doc资料.docx_第1页
第1页 / 共21页
用VB写高效的图像处理程序doc资料.docx_第2页
第2页 / 共21页
用VB写高效的图像处理程序doc资料.docx_第3页
第3页 / 共21页
用VB写高效的图像处理程序doc资料.docx_第4页
第4页 / 共21页
用VB写高效的图像处理程序doc资料.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

用VB写高效的图像处理程序doc资料.docx

《用VB写高效的图像处理程序doc资料.docx》由会员分享,可在线阅读,更多相关《用VB写高效的图像处理程序doc资料.docx(21页珍藏版)》请在冰豆网上搜索。

用VB写高效的图像处理程序doc资料.docx

用VB写高效的图像处理程序doc资料

 

用VB写高效的图像处理程序

用VB写高效的图像处理程序

自盘古开天地以来(好像夸张了点),一直有人抱怨VB程序速度慢。

特别是图像处理,被认为是VB的禁区。

说起来也是,市面上的关于VB的图像处理的数据都是先讲计算公式,再直接用PSet(或API函数SetPixel)逐点画(至少我见过的书都是这样)。

效果是办到了,但速度慢得离谱:

对一幅640*480的图像进行半透明合并就需要10秒钟;而在PhotoShop中,只要一设置图层的透明度,半透明效果立即呈现。

难怪有人说VB的闲话。

  但这并不表示VB不能写高速的图像处理程序,速度慢是因为没有使用正确的方法。

  从VB5开始,能以本机代码编译成exe文件,所以不存在代码执行速度的问题。

那么,是什么拖慢了速度呢?

就是PSet和SetPixel!

PSet把浮点形式的坐标转为像素单位,再交给SetPixel处理。

而SetPixel呢,坐标系转化、剪裁区域判断、将颜色匹配为设备支持的最接近的,最后还要根据不同的颜色格式寻址、为将颜色写入其所在位进行位运算。

经过这么多层处理,速度不慢才怪。

  那么,怎样才能提高处理速度呢?

使用DIB,直接对位图所在内存进行操作,速度可以大大提高。

现在看看,这只是一个简单的色彩演示程序。

CPU:

赛扬333;内存:

PC100(很老的概念了)的SDRAM,128MB;单位:

毫秒

Windows98

WindowsXP

说 明

VB_PSet

1,199.4553

786.1885

在VB使用PSet画的

VB_SetPixel

872.3621

451.3712

在VB使用SetPixelV画的

VB_DIB

8.2218

8.2226

在VB使用DIB画的

VB_DIB_Ptr

9.6783

9.4420

在VB使用DIBSection+模拟指针画的

VC(Debug)

6.6896

6.6503

VC写的(Debug版)

VC(Release)

3.2736

3.6247

VC写的(Release版)

  从这个表中可看出:

 

  1.VC比VB_DIB、VB_DIB_Ptr快两倍,这是因为SafeArray结构的数组比真正的指针慢,但也不是某些人所说的70~100倍;

  2.VB_DIB_Ptr比VB_DIB慢一点,这是因为模拟指针本来就是靠SafeArray结构的数组,而且模拟指针需要对两个数组进行操作,所以速度慢一点;

  3.真正差了70~100倍是VB_PSet和VB_SetPixel,特别是VB_PSet在Windows98下与VB_DIB差了145倍。

  以上可证,速度慢的原因是SetPixel非常低效,而并不是VB的问题。

虽然VC的的确比较快,但是我写这篇文章不是为了讨论速度极限(否则这篇文章会改名为《如何用汇编写高速的图像处理程序》),而是为了告诉大家如何在VB中写能够实时处理的图像处理程序。

 

  在Windows3.0以前,Windows系统用的是DDB(设备有关位图)。

DDB没有调色板,显示的颜色依赖硬件,处理色彩很不方便。

所以Microsoft在Windows3.0中重新定义了BMP文件格式(BMP3.0),使其支持设备无关位图——也就是DIB。

  时至今日,BMP的版本号已升至5.0(WindowsNT4.0、Windows95定义了BMP4.0,Windows98、Windows2000定义了BMP5.0),但基本结构没有变——仍是BMP文件头和DIB组成:

BMP文件

BITMAPFILEHEADER

BMP文件头

DIB

BITMAPINFOHEADER

位图信息头

RGBQUAD[]

调色板

位图数据

(#代表可以不填(=0)的项目) 

BMP文件头——BITMAPFILEHEADER

原型定义:

typedefstructtagBITMAPFILEHEADER{//bmfhWORDbfType;DWORDbfSize;WORDbfReserved1;WORDbfReserved2;DWORDbfOffBits;}BITMAPFILEHEADER;

VB声明:

TypeBITMAPFILEHEADERbfType(0to1)AsBytebfSizeAsLongbfReserved1AsIntegerbfReserved2AsIntegerbfOffBitsAsLongEndType

说明:

bfType

指示文件的类型,必须是“BM”

bfSize#

指示文件的大小,包括BITMAPFILEHEADER

bfReserved1

保留,=0

bfReserved2

保留,=0

bfOffBits#

从文件头到位图数据的偏移字节数

文件信息头——BITMAPINFOHEADER

原型定义:

typedefstructtagBITMAPINFOHEADER{//bmihDWORDbiSize;LONGbiWidth;LONGbiHeight;WORDbiPlanes;WORDbiBitCount;DWORDbiCompression;DWORDbiSizeImage;LONGbiXPelsPerMeter;LONGbiYPelsPerMeter;DWORDbiClrUsed;DWORDbiClrImportant;}BITMAPINFOHEADER;

VB声明:

TypeBITMAPINFOHEADERbiSizeAsLongbiWidthAsLongbiHeightAsLongbiPlanesAsIntegerbiBitCountAsIntegerbiCompressionAsLongbiSizeImageAsLongbiXPelsPerMeterAsLongbiYPelsPerMeterAsLongbiClrUsedAsLongbiClrImportantAsLongEndType

说明:

biSize

BITMAPINFOHEADER结构的大小。

BMP有多个版本,就靠biSize来区别:

 

  BMP3.0:

BITMAPINFOHEADER(=40)

  BMP4.0:

BITMAPV4HEADER(=108)

  BMP5.0:

BITMAPV5HEADER(=124)

biWidth

位图的高度,单位是像素

biHeight

位图的宽度,单位是像素

biPlanes

设备的位平面数。

现在都是1

biBitCount

图像的颜色位数

  0:

当biCompression=BI_JPEG时必须为0(BMP5.0)

  1:

单色位图

  4:

16色位图

  8:

256色位图

  16:

增强色位图,默认为555格式

  24:

真彩色位图

  32:

32位位图,默认情况下Windows不会处理最高8位,可以将它作为自己的Alpha通道

biCompression

压缩方式

  BI_RGB:

无压缩

  BI_RLE8:

行程编码压缩,biBitCount必须等于8

  BI_RLE4:

行程编码压缩,biBitCount必须等于4

  BI_BITFIELDS:

指定RGB掩码,biBitCount必须等于16、32

  BI_JPEG:

JPEG压缩(BMP5.0)

  BI_PNG:

PNG压缩(BMP5.0)

biSizeImage#

实际的位图数据所占字节(biCompression=BI_RGB时可以省略)

biXPelsPerMeter#

目标设备的水平分辨率,单位是每米的像素个数

biYPelsPerMeter#

目标设备的垂直分辨率,单位是每米的像素个数

biClrUsed#

使用的颜色数(当biBitCount等于1、4、8时才有效)。

如果该项为0,表示颜色数为2^biBitCount

biClrImportant#

重要的颜色数。

如果该项为0,表示所有颜色都是重要的

调色板

  只有biBitCount等于1、4、8时才有调色板。

调色板实际上是一个数组,元素的个数由biBitCount和biClrUsed决定。

原型定义:

typedefstructtagRGBQUAD{//rgbqBYTErgbBlue;BYTErgbGreen;BYTErgbRed;BYTErgbReserved;}RGBQUAD;

VB声明:

PrivateTypeRGBQUADrgbBlueAsBytergbGreenAsBytergbRedAsBytergbReservedAsByteEndType

说明:

rgbBlue

蓝色分量

rgbGreen

绿色分量

rgbRed

红色分量

rgbReserved#

保留,=0

位图数据

◆扫描行:

  一行的图像数据叫做一个扫描行。

一个扫描行的长度必须是4的倍数(字节),如果不是,则需要补齐。

计算公式:

LineBytes=((biWidth*biBitCount+31)And&HFFFFFFE0)\8 

  由于BMP设定者认为数学坐标系更总要,所以DIB的扫描行是逆序存储的(相对于屏幕坐标系而言),即屏幕上的第一行是DIB位图数据的最后一行。

◆1位色:

  用1位表示一个像素,所以一个字节可以表示8个像素。

坐标是从最左边(最高位)开始的,而不是一般情况下的最低位。

在内存的摆放形式如下:

字节

0

...

7

6

5

4

3

2

1

0

像素

0

1

2

3

4

5

6

7

◆4位色:

  用4位表示一个像素,所以一个字节可以表示2个像素。

坐标是从最左边(最高位)开始的,而不是一般情况下的最低位。

在内存的摆放形式如下:

字节

0

...

7

6

5

4

3

2

1

0

像素

0

1

像素位

3

2

1

0

3

2

1

0

◆8位色:

 

  用8位表示一个像素,所以一个字节刚好只能表示一个像素。

在内存的摆放形式如下:

字节

0

1

...

像素

0

1

◆16位色:

  用16位表示一个像素,所以两个字节可以表示1个像素。

默认情况下16位DIB是555格式,最高位无效(这对VB是个福音,因为VB没有16位无符号型)。

在内存的摆放形式如下(PC机是低字节在前):

字节

0

1

2

3

...

7

6

5

4

3

2

1

0

7

6

5

4

3

2

1

0

7

6

5

4

3

2

1

0

7

6

5

4

3

2

1

0

像素

0

1

RGB

G

B

x

R

G

G

B

x

R

G

RGB位

2

1

0

4

3

2

1

0

0

4

3

2

1

0

4

3

2

1

0

4

3

2

1

0

0

4

3

2

1

0

4

3

◆24位色:

 

  用24位表示一个像素,所以三个字节可以表示1个像素。

注意它的顺序是BGR,而不是传统的RGB。

在内存的摆放形式如下:

字节

0

1

2

3

4

5

...

像素

0

1

RGB

B

G

R

B

G

R

◆32位色:

  用32位表示一个像素,所以四个字节可以表示1个像素。

注意绝大多数的GDI函数不会处理Alpha通道(只有AlphaBlend支持)。

在内存的摆放形式如下:

字节

0

1

2

3

4

5

6

7

...

像素

0

1

RGB

B

G

R

A

B

G

R

A

SetDIBitsToDevice

原型定义:

intSetDIBitsToDevice(HDChDC,//handletodevicecontextintXDest,//x-coordinateofupper-leftcornerofdest.rect.intYDest,//y-coordinateofupper-leftcornerofdest.rect.DWORDdwWidth,//sourcerectanglewidthDWORDdwHeight,//sourcerectangleheightintXSrc,//x-coordinateoflower-leftcornerofsourcerect.intYSrc,//y-coordinateoflower-leftcornerofsourcerect.UINTuStartScan,//firstscanlineinarrayUINTcScanLines,//numberofscanlinesCONSTVOID*lpvBits,//addressofarraywithDIBbitsCONSTBITMAPINFO*lpbmi,//addressofstructurewithbitmapinfo.UINTfuColorUse//RGBorpaletteindexes);

VB声明:

DeclareFunctionSetDIBitsToDeviceLib"gdi32.dll"(ByValhDCAsLong,ByValXDestAsLong,ByValYDestAsLong,ByValdwWidthAsLong,ByValdwHeightAsLong,ByValXSrcAsLong,ByValYSrcAsLong,ByValuStartScanAsLong,ByValcScanLinesAsLong,lpvBitsAsAny,lpbmiAsAny,ByValfuColorUseAsLong)AsLong

说明:

将一幅与设备无关位图的全部或部分数据直接复制到一个设备。

这个函数在设备中定义了一个目标矩形,以便接收位图数据。

它也在DIB中定义了一个源矩形,以便从中提取数据

返回值:

如函数执行成功,返回欲复制的扫描线的数量;如返回常数GDI_ERROR,表示出错

参数:

hDC

一个设备场景的句柄。

该场景用于接收位图数据

XDest

指定绘制区域的左上角X坐标

YDest

指定绘制区域的左上角Y坐标

dwWidth

指定绘制区域的高度

dwHeight

指定绘制区域的宽度

XSrc

矩形在DIB中的起点X坐标

YSrc

矩形在DIB中的起点Y坐标

uStartScan

lpvBits中第一条扫描线的编号。

如lpbmi之BITMAPINFOHEADER部分的biHeight字段是正数,那么这条扫描线就会从位图的底部开始计算;如果是负数,就从顶部开始计算

cScanLines

欲复制的扫描线数量

lpvBits

指向一个缓冲区的指针。

这个缓冲区包含了以DIB格式描述的位图数据;这种格式是由lpbmi指定的

lpbmi

指向BITMAPINFO(为兼容BMP4/5而声明成Any),对DIB的格式和颜色进行描述的一个结构

fuColorUse

DIB_PAL_COLORS

颜色表是一个整数数组,其中包含了与目前选入hDC设备场景的调色板相关的索引

DIB_RGB_COLORS

颜色表包含了RGB颜色

StretchDIBits

原型定义:

intStretchDIBits(HDChDC,//handletodevicecontextintXDest,//x-coordinateofupper-leftcornerofdest.rectangleintYDest,//y-coordinateofupper-leftcornerofdest.rectangleintnDestWidth,//widthofdestinationrectangleintnDestHeight,//heightofdestinationrectangleintXSrc,//x-coordinateofupper-leftcornerofsourcerectangleintYSrc,//y-coordinateofupper-leftcornerofsourcerectangleintnSrcWidth,//widthofsourcerectangleintnSrcHeight,//heightofsourcerectangleCONSTVOID*lpBits,//addressofbitmapbitsCONSTBITMAPINFO*lpBitsInfo,//addressofbitmapdataUINTiUsage,//usageflagsDWORDdwRop//rasteroperationcode);

VB声明:

DeclareFunctionStretchDIBitsLib"gdi32"(ByValhDCAsLong,ByValXDestAsLong,ByValYDestAsLong,ByValnDestWidthAsLong,ByValnDestHeightAsLong,ByValXSrcAsLong,ByValYSrcAsLong,ByValnSrcWidthAsLong,ByValnSrcHeightAsLong,lpBitsAsAny,lpBitsInfoAsAny,ByValwUsageAsLong,ByValdwRopAsLong)AsLong

说明:

根据一幅与设备无关的位图创建一幅与设备有关的位图

返回值:

执行成功返回位图句柄,零表示失败

参数:

hDC

一个设备场景的句柄,该设备场景定义了要创建的与设备有关位图的配置信息

XDest

指定绘制区域的左上角X坐标

YDest

指定绘制区域的左上角Y坐标

nDestWidth

指定绘制区域的高度

nDestHeight

指定绘制区域的宽度

XSrc

矩形在DIB中的起点X坐标

YSrc

矩形在DIB中的起点Y坐标

nSrcWidth

指定原位图绘制区域的左上角X坐标

nSrcHeight

指定原位图绘制区域的左上角Y坐标

lpBits

指向一个缓冲区的指针。

这个缓冲区包含了以DIB格式描述的位图数据;这种格式是由lpBitsInfo指定的

lpBitsInfo

指向BITMAPINFO(为兼容BMP4/5而声明成Any),对DIB的格式和颜色进行描述的一个结构

iUsage

DIB_PAL_COLORS

颜色表是一个整数数组,其中包含了与目前选入hDC设备场景的调色板相关的索引

DIB_RGB_COLORS

颜色表包含了RGB颜色

dwRop

欲进行的光栅运算

CreateDIBitmap

原型定义:

HBITMAPCreateDIBitmap(HDChDC,//handletodevicecontextCONSTBITMAPINFOHEADER*lpbmih,//pointertobitmapsizeandformatdataDWORDfdwInit,//initializationflagCONSTVOID*lpbInit,//pointertoinitializationdataCONSTBITMAPINFO*lpbmi,//pointertobitmapcolor-formatdataUINTfuUsage//color-datausage);

VB声明:

DeclareFunctionCreateDIBitmapLib"gdi32"(ByValhDCAsLong,lpbmihAsAny,ByValfdwInitAsLong,lpbInitAsAny,lpbmiAsAny,ByValfuUsageAsLong)AsLong

说明:

将一幅与设备无关位图的全部或部分数据直接复制到一个设备。

这个函数在设备中定义了一个目标矩形,以便接收位图数据。

它也在DIB中定义了一个源矩形,以便从中提取数据

返回值:

执行成功则返回扫描线的数量,零表示失败。

会设置GetLastError

参数:

hDC

一个设备场景的句柄。

该场景用于接收位图数据

lpbmih

BITMAPINFOHEADER(为兼容BMP4/5而声明成Any),对DIB的格式进行描述的一个结构

fdwInit

如不应对位图数据进行初始化,那么设为零。

如设为CBM_INIT,表示根据lpbInit和lpbmi参数对位图进行初始化

lpbInit

指向一个缓冲区的指针。

这个缓冲区包含了以DIB格式描述的位图数据;这种格式是由lpbmi指定的

lpbmi

指向BITMAPINFO(为兼容BMP4/5而声明成Any),对DIB的格式和颜色进行描述的一个结构

fuUsage

DIB_PAL_COLORS

颜色表是一个整数数组,其中包含了与目前选入hDC设备场景的调色板相关的索引

DIB_RGB_COLORS

颜色表包含了RGB颜色

CreateDIBSection

原型定义:

HBITMAPCreateDIBSection(HDChDC,//handletodevicecontextCONSTBITMAPINFO*lpbmi,//pointertostructurecontainingbitmapsize,format,andcolordataUINTiUsage,//colordatatypeindicator:

RGBvaluesorpaletteindexesVOID*ppvBits,//pointertovariabletoreceiveapointertothebitmap´sbitvaluesHANDLEhSection,//optionalhandletoaf

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 可爱清新

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1