当前位置: 开源爱好者 » 编程教程 » VC++教程 » 正文

VC++ 存取图像字段

本源码以操作Access 数据库为例子,介绍如何从数据库中读取图像字段,并显示出来。编译并运行本例程序,如下图所示,单击【载入图片】按钮,在对话框窗口的左侧显示一个位图。

 

实现方法:用CByteArray 保存图像字段,先从该二进制数组中分别读取BITMAPINFOHEADER、BITMAPINFO等位图信息,然后用CreateDIBitmap 创建一位图文件并显示。程序代码编写如下:
(1)通过AppWizard 生成基于对话框的应用程序BmpField。
(2)创建名为BmpField 的Access 数据库,包含一个表Table,其中有字段ID,SomeText 和Images,类型分别为自动编号,文本和OLE 对象,其中ID 设为主键,并给增加两条记录,其中Images对应两副位图。将该数据库保存在应用程序BmpField 的根目录下。
(3)通过ClassWizard 新建类CImageData,基类为CDaoRecordset,选择第二步创建的数据库BmpField 和其惟一的表Table。
(4)更改CImageData 类的成员变量m_Images 的类型,由“CLongBinary m_Images; ” 变为“CbyteArraym_Images;”。
(5)更改CImageData 类的DoFieldExchange,其代码如下:

void CImageData::DoFieldExchange(CDaoFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(CImageData)
pFX->SetFieldType(CDaoFieldExchange::outputColumn);
DFX_Long(pFX, _T("[ID]"), m_ID);
DFX_Text(pFX, _T("[SomeText]"), m_SomeText);
DFX_Binary(pFX, _T("[Images]"), m_Images);
//}}AFX_FIELD_MAP
}

(6)更改CImageData 类的GetDefaultDBName 函数,使用相对路径,其代码如下:

//使用相对路径
CString CImageData::GetDefaultDBName()
{
return _T("BmpField.mdb");
}

(7)为了获得CDaoRecordSet 的支持,在stafx.h 中加如下代码:

#include <afxdao.h>

(8)给对话框增加一个CBitmap 类型的成员变量,其代码如下:

CBitmap OleBmp;

(9)给对话框增加成员函数ReadFromBLOB,用来从数据库中读位图数据,并且创建位图,其定义如下:

//读位图数据,并创建位图
BOOL CBmpFieldDlg::ReadFromBLOB(CByteArray & DBArray)
{
CByteArray Array;
Array.Copy( DBArray);
//获得位图文件头信息长度
int HeaderLen = 78 + sizeof(BITMAPFILEHEADER);
Array.RemoveAt( 0, HeaderLen ); // I cut all Headers
//获得位图信息
BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)
Array.GetData() ;
BITMAPINFO &bmInfo = *(LPBITMAPINFO)Array.GetData() ;
//获得位图颜色数
int nColors = bmiHeader.biClrUsed ?
bmiHeader.biClrUsed : 1 << bmiHeader.biBitCount;
//获得位图数据
LPVOID lpDIBBits;
if( bmInfo.bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors
+ bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ?
3 : 0));
else
lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
CClientDC dc(NULL);
//创建位图
HBITMAP hBmp = CreateDIBitmap( dc.m_hDC,
&bmiHeader,
CBM_INIT,
lpDIBBits,
&bmInfo,
DIB_RGB_COLORS);
OleBmp.Attach( hBmp );
//清除临时数组
Array.RemoveAll();
return TRUE;
}

(10)在对话框的OnPaint 函数中显示位图,其代码如下:

//显示位图
void CBmpFieldDlg::OnPaint()
{
//获得DC
CPaintDC dc(this);
if (!(OleBmp.m_hObject == NULL))
{
//创建内存设备场景
CDC dcMem;
dcMem.CreateCompatibleDC( &dc );
CBitmap* pbmpOld ;
BITMAP BmpSize ;
OleBmp.GetBitmap(&BmpSize); //get Image Size
pbmpOld = dcMem.SelectObject(&OleBmp);
//显示位图
dc.StretchBlt( 5, 5, 150, 200, &dcMem, 0, 0, BmpSize.bmWidth, BmpSize.bmHeight, SRCCOPY);
dcMem.SelectObject( pbmpOld );
}
}

(11)给对话框增加【LoadImage】按钮,其响应函数如下:

//获得位图数据
void CBmpFieldDlg::OnLoadimag()
{
//打开数据库
CImageData db;
db.Open();
if(m_bLoad==false)
{
ReadFromBLOB(db.m_Images);
//显示位图
Invalidate();
}
m_bLoad=true;
//关闭数据库
db.Close();
}

VC++存取图像字段完整源码

CopyRight 2018© 开源爱好者 All Rights Reserved 豫ICP备16030607号 隐私声明 网站地图