向数据库中存取图片(BITMAP)

 

向数据库中存取图片(BITMAP)

BITMAP
测试环境:windows xp2 vc6.0 access2003/sql2000
当前时间所限就先把关于BMP文件的操作总结了一下,在接下来会再总结一下其它几种图片在数据库的操作的。
转入下文:
个人感觉向数据库中写入和读取位图,也没有什么难的,重点还是在于对位图文件的读取,如果这一关能把握好的话,那也就没有问题了。如果哪位看过我的一篇《VC下显示位图的几种方法》其中有一段是关于,直接读取位图文件的,如果看明白了它,也今天这几个问题就会很好明白了。
进入正题:既然是向数据库中添加位图信息,那么有必须明白我们的数据是以什么形式存放在数据库的,当然没有别的方法,只能是二进制了,所以在创建数据库的时候,一定要注意选择的字段的类型,不然是添加下进去的。(刚开始的时候,我就遇到了这个问题,费了好长时间才搞定的。Access中的字段定义为”  OLE 对象”,sql2000中字义为image就行了。)
1> 读取一个位图,
CFile FilePic;//用来读取位图文件
DWORD FileLen=0;//位图的长度
char* FileBuff;//用于存放位图信息

if(!FilePic.Open(FilePath,Cfile::modeRead))//打开位图文件
{
  MessageBox("打开图片信息失败!");
  return false;
}
FileLen=FilePic.GetLength();//得到位图的长度
FileBuff=new char[FileLen+1];//给位图文件申请内在空间
memset(FileBuff,0,FileLen+1);//初始化位图文件的空间
if(!FileBuff)//判断位图空间是否申请成功
{
  MessageBox("给图片分配空间失败!");
  return false;
}
if(FilePic.Read(FileBuff,FileLen)!=FileLen)//读取位图信息,存入到FileBuff中去
{
  MessageBox("读取图片信息失败!");
  return false;
}
2> 把位图信息存放到VARIANT对象中,存入数据库中
char* pBuff= FileBuff;
VARIANT varPic;//该对象用于存放位图信息
SAFEARRAY *safeArray;//定义一个SAFEARRAY结构对象(对于这个东西,会有专门的文档大家可以看一下,网上很多,不过都差不多,最好去MSDN上找一下)
SAFEARRAYBOUND rgsabound[1];//此结构体用来定义SAFEARRAY的边界,详情见MSDN
if(pBuff)//判断位图文件是否为空
{
  rgsabound[0].lLbound=0;//定义下界
  rgsabound[0].cElements=DwPic;//定义上限
  safeArray=SafeArrayCreate(VT_UI1,1,rgsabound);// 使用SafeArrayCreate在堆上创建一维数组
  for(long i=0;i<(long)DwPic;i++)
  {
   SafeArrayPutElement(safeArray,&i,pBuff++);//传值
  }
  varPic.vt=VT_ARRAY|VT_UI1;//把值给VARIANT对象
  varPic.parray=safeArray; //把值给VARIANT对象
}
3> 把数据写到数据库中
ACCESS2003:
pRecordset->AddNew();
try
{
pRecordset->PutCollect("Name",_variant_t("zhang1"));
pRecordset->GetFields()->GetItem("Picture")->AppendChunk(varPic);
}
catch(_com_error e)
{
  MessageBox("Add pic to access is falied!");
}
pRecordset->Update();
sql2000:
pRecordsetSql->AddNew();

try
{
  pRecordsetSql->PutCollect("Name",_variant_t("zhang1"));
  pRecordsetSql->GetFields()->GetItem("Pic")->AppendChunk(SavePic(FileBuff,FileLen));
}
catch(_com_error e)
{
  MessageBox("Add picture to sqlserver2000 is failed!");
}
pRecordsetSql->Update();
在数据库中读取位图信息并显示出来:
其实读取并且显示过程的过程也非常的简单,主要是把它们在数据库中读取出来,放到一个内存空间中,然后把这此些读取出来的信息再转换成一个BITMAP就可以显示了,(如果不明白怎么转换的话,可以看一下关于位图的文件格式,我关于它的一些信息,也可以参与一下本人的《VC下显示位图的几种方法》里面有详细的解释)
进入正题:
_variant_t TheValue;//存储读出来的数据
DWORD DataSize;//在数据库中读取出来的位图的大小

char *pBuff;//用于存放位图的内存空间
CString str="select * from Picture";//SQL语句^_^
BSTR bstrRecordset=str.AllocSysString();//这句也不用解释了吧
HBITMAP hBitmap;//定义一个HBITMAP对象,用于显示位图用
try
{
  pRecordset->Open(bstrRecordset,pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
  pRecordset->MoveLast();
  TheValue=pRecordset->GetCollect("Picture");//读取字段一
DataSize=pRecordset->GetFields()->GetItem("Picture")->ActualSize;//得到位图字段的大小
  if(DataSize>0)//判断那个位图字段是否为空
  {
   if(TheValue.vt==(VT_ARRAY|VT_UI1))
   {
    if(pBuff=new char[DataSize+1])
    {
     char *buff;
/***********************主要也就下面这几句画,其它的和显示位图相似**************************/
     SafeArrayAccessData(TheValue.parray,(void**)&buff);//把位图数据放到buff中去
     memcpy(pBuff,buff,DataSize);//把位图数据放到pBuff中
     SafeArrayUnaccessData(TheValue.parray);//释放
     hBitmap=MemTOPic(pBuff);//这是一个自字义
    }
   }
  }
}
catch(_com_error e)
{
  MessageBox("打开数据表失败!");
  return ;
}
/******************根据HBITMAP把位图显示出来************************/
CBitmap cBitmap;
CClientDC *pDC=new CClientDC(this);
BITMAP bitmap;
CDC MemDC;
cBitmap.Attach(hBitmap);
MemDC.CreateCompatibleDC(pDC);
MemDC.SelectObject(&cBitmap);
cBitmap.GetBitmap(&bitmap);
pDC->StretchBlt(0,0,bitmap.bmWidth,bitmap.bmHeight,&MemDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
MemDC.DeleteDC();
::DeleteObject(&bitmap);
/*************自定义函数************把内存数据转为HBITMAP***************************/
HBITMAP CDBPicDllDlg::MemTOPic(char *buff)
{

HBITMAP hBitmap=NULL;
LPSTR hDib=NULL;
LPSTR PicBuff=NULL;
PicBuff=buff;
LPVOID pDibBit=NULL;
BITMAPFILEHEADER bmpHead;//位图头结构
DWORD LenBmpHead;
LenBmpHead=sizeof(BITMAPFILEHEADER);
strncpy((LPSTR)&bmpHead,PicBuff,LenBmpHead);
// memcpy((LPSTR)&bmpHead,PicBuff,LenBmpHead);
if(bmpHead.bfType!=(*(WORD*)"BM"))//(*(WORD*)"BM")
{
  MessageBox("您选择的图片不是bmp图片!");
  return NULL;
}
hDib=PicBuff+LenBmpHead;//hDib=PicBuff
BITMAPINFOHEADER  &BitmapInfoHead=*(LPBITMAPINFOHEADER)hDib;
BITMAPINFO &BitmapInfo=*(LPBITMAPINFO)hDib;
pDibBit=PicBuff+((BITMAPFILEHEADER*)PicBuff)->bfOffBits;
CClientDC dc(this);
hBitmap=CreateDIBitmap(dc.m_hDC,&BitmapInfoHead,CBM_INIT,pDibBit,&BitmapInfo,DIB_RGB_COLORS);
return hBitmap;
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
在SQL2000下方法也是相同的,这里就不重复了。由于时间原因今天这里只是和大家讨论了BMP文件,接下来我会把一些关于JPG的文件的在数据库的读写方法总结出来,供大家交流之用。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值