首页 > 编程知识 正文

为什么函数太大影响效率(memcmp)

时间:2023-05-04 22:08:44 阅读:74724 作者:1217

BMP位图文件结构和平滑缩放

---用普通方法显示BMP位图,内存大、速度慢、图形缩小时失真大,用低色位数设备显示高色位数图形时失真大。 本文可以通过使用视频函数显示BMP位图来消除上述缺点。

----一、BMP文件结构

----1 .由BMP文件组成

---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。

---- 2. BMP文件标头

---- BMP文件的头部数据结构包含BMP文件类型、文件大小和位图开始位置等信息。

---其结构定义如下:

typedefstructtagbitmapfileheader

{

WORDbfType; //位图文件的类型必须是BM

DWORD bfSize; //位图文件的大小,以字节为单位

WORDbfReserved1; //位图文件的保留字。 必须为0

WORDbfReserved2; //位图文件的保留字。 必须为0

DWORD bfOffBits; //相对于位图,位图数据开始位置

//文件头的偏移显示,以字节为单位

}位图文件头;

---- 3 .位图信息头

----

BMP位图信息头部数据用于描述诸如位图的尺寸之类的信息。

typedefstructtagbitmapinfoheader {

DWORD biSize; //本结构占用的字节数

龙珠国际; //位图的宽度,以像素为单位

龙比海; //位图高度,以像素为单位

WORD biPlanes; //目标设备的级别必须为1

WORD biBitCount//像素所需的位数必须为1 (双色)。

//4(16色)、8 (256色)或24 (真颜色)之一

DWORD biCompression; //位图压缩类型必须为0 (不压缩)。

//1(bi_RLE8压缩类型)或2 )2(BI_RLE4压缩类型)

DWORD biSizeImage; //位图的大小,以字节为单位

LONGbiXPelsPerMeter; //位图的水平分辨率、每米的像素数

LONGbiYPelsPerMeter; //位图的垂直分辨率、每米的像素数

DWORD biClrUsed; //位图中实际使用的颜色表的颜色数

DWORD biClrImportant; //位图显示中的重要颜色数

} bitmapinfo头部;

---- 4 .颜色表

---颜色表用于说明位图中的颜色,有几个表条目。 每个表条目都是RGB四元类型的结构,用于定义颜色。 RGB四元结构的定义为以下:

typedef struct tagRGBQUAD {

BYTErgbBlue; //蓝色的亮度(值范围为0-255 ) )。

BYTErgbGreen; //绿色的亮度(值范围为0-255 ) )。

字节; //红色的亮度(值的范围为0-255 ) )。

已隐藏; //保留,必须为0

} RGBQUAD;

颜色表中RGB四元结构数据的数量由bi比特计数确定:

bibitcount=1、4、8时,分别有2、16、256个表项目;

如果biBitCount=24,则没有颜色表条目。

位图信息头部和颜色表构成位图信息,BITMAPINFO结构定义如下:

typedef struct tagBITMAPINFO {

BITMAPINFOHEADER bmiHeader; //位图信息头

RGB四足动物颜色[1]; //颜色表

(} BITMAPINFO;

---- 5 .位图数据

---位图数据记录了位图的每个像素值。 记录顺序在扫描行内从左到右,在扫描行之间从下到上。 位图中一个像素的值所占的字节数:

如果biBitCount=1,则8个像素占用1字节;

如果biBitCount=4,则两个像素占一个字节;

如果biBitCount=8,则一个像素占用一个字节;

如果biBitCount=24,则一个像素占用3字节;

在Windows上,一个扫描行所占的字节数必须为

的倍数(也就是long单位),不够的用0填充,

扫描线所占字节数的计算方法:

datasizeperline=(bi width * bi位计数31 )/8;

//1扫描行所占的字节数

datasizeperline=datasizeperline/4 * 4; //字节数必须是4的倍数

位图数据的大小(未压缩时) :

datasize=datasizeperline * biheight;

----二、BMP位图常规表示

方法
---- 1. 申请内存空间用于存放位图文件
---- GlobalAlloc(GHND,FileLength);
---- 2. 位图文件读入所申请内存空间中
---- LoadFileToMemory( mpBitsSrc,mFileName);
---- 3. 在OnPaint等函数中用创建显示用位图
---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容DC,
---- 用SelectBitmap()选择显示位图。
---- 4. 用BitBlt或StretchBlt等函数显示位图
---- 5. 用DeleteObject()删除所创建的位图
---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上(如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。
---- 三、BMP位图缩放显示
---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形进行淡化(Dithering)处理。淡化处理是一种图形算法,可以用来在一个支持比图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下:
---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中
---- 2. 申请内存空间用于存放位图文件
---- GlobalAlloc(GHND,FileLength);
---- 3. 位图文件读入所申请内存空间中
---- LoadFileToMemory( mpBitsSrc,mFileName);
---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图
---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中
---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通过直接处理位图数据,可以制作简单动画。
---- 四、CViewBimap类编程要点
---- 1. 在CViewBimap类中添加视频函数等成员
HDRAWDIB m_hDrawDib; // 视频函数
HANDLEmhBitsSrc; // 位图文件句柄(内存)
LPSTR mpBitsSrc; // 位图文件地址(内存)
BITMAPINFOHEADER *mpBitmapInfo; // 位图信息头
---- 2. 在CViewBimap类构造函数中添加打开视频函数
---- m_hDrawDib= DrawDibOpen();
---- 3. 在CViewBimap类析构函数中添加关闭视频函数
if( m_hDrawDib != NULL)
{
DrawDibClose( m_hDrawDib);
m_hDrawDib = NULL;
}
---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw()
voidCViewBitmap::OnPaint()
{
CPaintDC dc(this); // device context for painting
GraphicDraw( );
}
voidCViewBitmap::GraphicDraw( void )
{
CClientDC dc(this); // device context for painting
BITMAPFILEHEADER *pBitmapFileHeader;
ULONG bfoffBits= 0;
CPoint Wid;
// 图形文件名有效 (=0 BMP)
if( mBitmapFileType < ID_BITMAP_BMP ) return;
// 图形文件名有效 (=0 BMP)
// 准备显示真彩位图
pBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc;
bfoffBits= pBitmapFileHeader->bfOffBits;
// 使用普通函数显示位图
if( m_hDrawDib == NULL || mDispMethod == 0)
{
HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC,
mpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits,
(LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS); 
// 建立位图
HDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存
HBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象
// 成员CRect mDispR用于指示图形显示区域的大小.
// 成员CPoint mPos用于指示图形显示起始位置坐标.
if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() ))
mPos.x= mpBitmapInfo->biWidth - mDispR.Width() ;
if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
if( mPos.x < 0 ) mPos.x= 0;
if( mPos.y < 0 ) mPos.y= 0;
if( mFullViewTog == 0)
{
// 显示真彩位图
::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
hMemDC,mPos.x,mPos.y, SRCCOPY);
} else {
::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
hMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo-
>biHeight, SRCCOPY);
}
// 结束显示真彩位图
::DeleteObject(SelectObject(hMemDC,hBitmapOld)); 
// 删 除 位 图
} else {
// 使用视频函数显示位图
if( mPos.x > (mpBitmapInfo- >biWidth - mDispR.Width() ))
mPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ;
if( mPos.y > (mpBitmapInfo- >biHeight- mDispR.Height()))
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
if( mPos.x < 0 ) mPos.x= 0;
if( mPos.y < 0 ) mPos.y= 0;
// 显示真彩位图
DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE);
if( mFullViewTog == 0)
{
Wid.x= mDispR.Width();
Wid.y= mDispR.Height();
// 1:1 显示时, 不能大于图形大小
if( Wid.x > mpBitmapInfo- >biWidth )
Wid.x = mpBitmapInfo- >biWidth;
if( Wid.y > mpBitmapInfo- >biHeight)
Wid.y = mpBitmapInfo- >biHeight;
DrawDibDraw( m_hDrawDib, dc.GetSafeHdc()
, 0, 0, Wid.x, Wid.y,
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),
mPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL);
} else {
DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(),
0, 0, mDispR.Width(), mDispR.Height(),
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),
0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight,
DDF_BACKGROUNDPAL);
}
}
return;
}

 

http://blog.csdn.net/pizi0475/article/details/5363606


版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。