您的位置:首页 > 其它

VC下显示位图的几种方法

2013-04-14 21:57 423 查看
VC下显示位图的几种方法

总结一下关于位图的几种用法。

说到这还是开头给大家介绍一下,有关位图的知识吧,以及对于我们比较有用的几个关于位图的结构体。

一.位图结构如下:

---- 一、BMP文件结构

---- 1. BMP文件组成

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

---- 2. BMP文件头

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

---- 其结构定义如下:

typedef struct tagBITMAPFILEHEADER

{

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

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

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

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

DWORD bfOffBits; // 位图数据的起始位置,以相对于位图

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

} BITMAPFILEHEADER;

---- 3. 位图信息头

BMP位图信息头数据用于说明位图的尺寸等信息。

typedef struct tagBITMAPINFOHEADER{

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

LONGbiWidth; // 位图的宽度,以像素为单位

LONGbiHeight; // 位图的高度,以像素为单位

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

WORD biBitCount// 每个像素所需的位数,必须是1(双色),

// 4(16色),8(256色)或24(真彩色)之一

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

// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一

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

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

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

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

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

} BITMAPINFOHEADER;

---- 4. 颜色表

颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:

typedef struct tagRGBQUAD {
BYTErgbBlue;// 蓝色的亮度(值范围为0-255)

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

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

BYTErgbReserved;// 保留,必须为0

} RGBQUAD;

颜色表中RGBQUAD结构数据的个数有biBitCount来确定:

当biBitCount=1,4,8时,分别有2,16,256个表项;

当biBitCount=24时,没有颜色表项。

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

typedef struct tagBITMAPINFO {

BITMAPINFOHEADER bmiHeader; // 位图信息头

RGBQUAD bmiColors[1]; // 颜色表

} BITMAPINFO;

下面我们介绍第一种办法:

//第一种方法,使用WM__CTRLCOLOR来实现

/*******************OnCtlColor中添加的代码*****************/

HBRUSH CDemoBitmapDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

{

HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

// TODO: Change any attributes of the DC here

//第一种实现方法

if(nCtlColor=CTLCOLOR_DLG)

{

return brush;

}

// TODO: Return a different brush if the default is not desired

return hbr;

}
BOOL CDemoBitmapDlg::OnInitDialog()

{

//第一种方法,使用wm_ctlcolor来实现

CBitmap bitmap;

bitmap.LoadBitmap(IDB_BITMAP1);

brush.CreatePatternBrush(&bitmap);//brush定义在头文件中CBrush burush

bitmap.DeleteObject();

}

第二种方法使用资源文件中导入的IDB_BITMAP来实现

第一步先在资源中导入一个位图:IDB_BITMAP1

void CDemoBitmapDlg::OnBtnBitmap()

{

// TODO: Add your control notification handler code here

/***************显示BITMAP的第二种方法**********************/

HBITMAP hBitmap;

CBitmap bitmap;

CClientDC *pDC;

pDC=new CClientDC(this);

hBitmap=(HBITMAP)::LoadImage(::AfxGetInstanceHandle(),"NetFriend.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);

bitmap.Attach(hBitmap);

CDC CDCompatible;

CDCompatible.CreateCompatibleDC(pDC);//创建兼容DC

CDCompatible.SelectObject(&bitmap);

/*********其它几种显示方式********/

/* pDC->BitBlt(0,0,200,200,&CDCompatible,0,0,SRCCOPY);

CDCompatible.SetBkMode(TRANSPARENT);

pDC->StretchBlt(0,0,352,288,&CDCompatible,0,0,352,288,SRCCOPY);

CDCompatible.CreateCompatibleDC(this->GetDC());

CDCompatible.SelectObject(&bitmap); */ //选择绘图对象

BITMAP bmp;

bitmap.GetBitmap(&bmp);

pDC->StretchBlt(0,0,bmp.bmWidth,bmp.bmHeight,&CDCompatible,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);

CDCompatible.DeleteDC();

::DeleteObject(&bitmap);

}

第三种方法是通过读取指定目录中的位图文件来显示(这里分别把它们显示在Picture控件和Static上面这也是大家通常要用到的):

void CDemoBitmapDlg::OnBtnPic()

{

// TODO: Add your control notification handler code here

/****************向PICTURE控件中动态添加位图****************************/

HBITMAP hBitmap;

CBitmap bitmap;

hBitmap=(HBITMAP)::LoadImage(::AfxGetInstanceHandle(),"NetFriend.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);

bitmap.Attach(hBitmap);

m_Pic.SetBitmap(hBitmap);
}

/****************在STATIC中显示位图*********************/

void CDemoBitmapDlg::OnBtnStatic()

{

// TODO: Add your control notification handler code here

CBitmap hbmp;

HBITMAP hbitmap;

//将pStatic指向要显示的地方

CStatic *pStaic;

pStaic=(CStatic*)GetDlgItem(IDC_IMAGE);

// pStaic=(CStatic*)GetDlgItem(IDC_BUTTON1);

//装载资源 MM.bmp是我的一个文件名,用你的替换

hbitmap=(HBITMAP)::LoadImage (::AfxGetInstanceHandle(),"NetFriend.bmp",

IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);

hbmp.Attach(hbitmap);

//获取图片格式

BITMAP bm;

hbmp.GetBitmap(&bm);

CDC dcMem;

dcMem.CreateCompatibleDC(GetDC());

CBitmap *poldBitmap=(CBitmap*)dcMem.SelectObject(hbmp);

CRect lRect;

pStaic->GetClientRect(&lRect);

//显示位图

pStaic->GetDC()->StretchBlt(lRect.left ,lRect.top ,lRect.Width(),lRect.Height(), &dcMem,0 ,0,bm.bmWidth,bm.bmHeight,SRCCOPY);

dcMem.SelectObject(&poldBitmap);

}

/*****************向BUTTON中添加ICON*****************************/

//方法和导入其它位图类似,在这里就只做一个说明一下就是了。

HICON hIco;

hIco=AfxGetApp()->LoadIcon(IDI_ICON1);

m_BtnBitmap.SetIcon(hIco);

第四种读取位图文件来显示位图:

void CDemoBitmapDlg::OnBtnBtmfile()

{

// TODO: Add your control notification handler code here

/*******************通过读取位图文件来显示位图**********************/

CString strFileName;

strFileName.Format("%s","NetFriend.bmp");

//成位图信息BITMAPINFO

BITMAPINFO *bitmapinfo=NULL;

BYTE *BmpData=NULL;

CFile file;//读取位图信息

//设置文件的打开方式

if(!file.Open(strFileName,Cfile::modeRead|Cfile::typeBinary))

{

return;

}

//BITMAP文件头结构体

BITMAPFILEHEADER BitmapHead;

//读取位图文件头

if(file.Read(&BitmapHead,sizeof(BITMAPFILEHEADER))!=sizeof(BITMAPFILEHEADER))

{

MessageBox("读取文件头失败!");

return;

}

if(BitmapHead.bfType!=0x4d42)

{

MessageBox("对不起,您读取的不是位图文件!");

return;

}

//位图信息

BITMAPINFOHEADER BitmapInfo;

if(file.Read(&BitmapInfo,sizeof(BITMAPINFOHEADER))!=sizeof(BITMAPINFOHEADER))

{

MessageBox("读取位图信息失败!");

return;

}

if(BitmapInfo.biBitCount!=24)

{

MessageBox("对不起,当前程序只支持24位位图信息!");

return;

}

bitmapinfo=(BITMAPINFO*)new char[sizeof(BITMAPINFOHEADER)];

if(!bitmapinfo)

{

MessageBox("内存分配失败!");

return;

}

/*把BMP位图信息头中的数据读取到位图信息结构中去.*/

memcpy(bitmapinfo,&BitmapInfo,sizeof(BITMAPINFOHEADER));

/*用来得到位图文件的大小*/

DWORD dataByte=BitmapHead.bfSize-BitmapHead.bfOffBits;

BmpData=(BYTE*)new char[dataByte];

if(!BmpData)

{

MessageBox("内存分配失败!");

delete bitmapinfo;

delete BmpData;

return;

}

if(file.Read(BmpData,dataByte)!=dataByte)

{

MessageBox("读取位图数据失败!");

return;

}

file.Close();

CClientDC *pDC=new CClientDC(this);

pDC->SetStretchBltMode(COLORONCOLOR);

StretchDIBits(pDC->GetSafeHdc(),200,0,BitmapInfo.biWidth,BitmapInfo.biHeight, 0,0,BitmapInfo.biWidth,BitmapInfo.biHeight,BmpData,bitmapinfo,DIB_RGB_COLORS,SRCCOPY);

}

最后给大家介绍两个显示位图的特效的例子更多的特效显示
1> 水平交错显示位图

void CListBmap::OnButton1()

{

// TODO: Add your control notification handler code here

HBITMAP hBitmap;

CBitmap cBitmap;

hBitmap=(HBITMAP)::LoadImage(::AfxGetInstanceHandle(),"NetFriend.bmp", IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);

cBitmap.Attach(hBitmap);

cBitmap.GetBitmap(&bitmap);

int i=0,j=0;

CClientDC *pDC=new CClientDC(this);

CDC memDC;

memDC.CreateCompatibleDC(GetDC());

memDC.SelectObject(&cBitmap);

for(i=0;i<bitmap.bmHeight;i+=2)

{

j=i;

while(j>0)

{

pDC->StretchBlt(0,j-1,bitmap.bmWidth,1,&memDC,0,bitmap.bmHeight-(i-j+1), bitmap.bmWidth,1,SRCCOPY);

pDC->StretchBlt(0,bitmap.bmHeight-j,bitmap.bmWidth,1,&memDC,0,i-j, bitmap.bmWidth,1,SRCCOPY);

j-=2;

}

Sleep(50);

}
}
2>雨点显示:

void CListBmap::OnButton2()

{

// TODO: Add your control notification handler code here
HBITMAP hBitmap;

CBitmap cBitmap;

hBitmap=(HBITMAP)::LoadImage(::AfxGetInstanceHandle(),"NetFriend.bmp", IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);

cBitmap.Attach(hBitmap);

cBitmap.GetBitmap(&bitmap);

int i=0,j=0;

CClientDC *pDC=new CClientDC(this);

CDC memDC;

memDC.CreateCompatibleDC(GetDC());

memDC.SelectObject(&cBitmap);

for ( i=0; i<=bitmap.bmHeight; i++ )

{

for ( j=0; j<=bitmap.bmHeight-i; j++ )

pDC->StretchBlt(

0,j,

//目标设备逻辑横、纵坐标

bitmap.bmWidth,1,

//显示位图的像素宽、高度

&memDC,

//源位图设备情境对象

0,bitmap.bmHeight-i,

//源位图的起始横、纵坐标

bitmap.bmWidth,1,

//源位图的像素宽、高度

SRCCOPY);

Sleep(20);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: