C++使用ADO实现存取图片的方法(2)
以下是读取图片数据并保存到本地的代码实现: OpenConnection();m_pRecord.CreateInstance(__uuidof(Recordset));CString strSQL;strSQL.Format(_T("Select * from Images where ID = 1"));try
以下是读取图片数据并保存到本地的代码实现:
OpenConnection(); m_pRecord.CreateInstance(__uuidof(Recordset)); CString strSQL; strSQL.Format(_T("Select * from Images where ID = 1")); try { m_pRecord->Open(strSQL.AllocSysString(), m_pConn.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText); } catch (_com_error e) { AfxMessageBox(_T("读取图片信息异常")); return; } LPVOID Data; char* pbuf = NULL; long lDatasize = m_pRecord->GetFields()->GetItem("ImageData")->ActualSize; //数据库中图像数据长度 CString imagename = m_pRecord->GetCollect("Name").bstrVal; if (lDatasize > 0) { _variant_t varBLOB; varBLOB = m_pRecord->GetFields()->GetItem("ImageData")->GetChunk(lDatasize); Data = new char[lDatasize+1]; if (varBLOB.vt == (VT_ARRAY|VT_UI1)) { SafeArrayAccessData(varBLOB.parray, (void **)&pbuf); memcpy(Data, pbuf, lDatasize); SafeArrayUnaccessData(varBLOB.parray); } } IStream* pStm; LONGLONG cb = lDatasize; HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb); LPVOID pvData; if (hGlobal != NULL) { pvData = GlobalLock(hGlobal); memcpy(pvData, Data, cb); GlobalUnlock(hGlobal); CreateStreamOnHGlobal(hGlobal, TRUE, &pStm); } else { AfxMessageBox(_T("Error")); return; } CLSID encoderClsid; GetEncoderClsid(L"image/bmp",&encoderClsid); //确定编码格式是bmp格式 Image image(pStm, TRUE); CString imagepath; imagepath.Format(_T("F:/200713454/%s"), imagename); image.Save(imagepath, &encoderClsid, NULL); //把image中的数据按照bmp编码格式存到本地 m_pRecord->Close(); m_pRecord = NULL; CloseConnection();
上面存储和读取数据的代码中用到了两个函数,GetEncoderClsid和SetImage2DB。它们的实现如下:
这个函数和上面的存/取函数都是一个类的成员函数,而m_pConn和m_pRecord是这个类的成员变量,所以
void CDlgTest::SetImage2DB(CString path) { VARIANT varChunk; SAFEARRAY* psa; SAFEARRAYBOUND rgsabound[1]; CFile f(path.operator LPCTSTR(),CFile::modeRead); BYTE bval[ChunkSize+1]; long uIsRead=0; while (1) { uIsRead=f.Read(bval,ChunkSize); if (uIsRead==0) break; rgsabound[0].cElements=uIsRead; rgsabound[0].lLbound=0; psa=SafeArrayCreate(VT_UI1,1,rgsabound); for (long index=0;index<uIsRead;index++) { if (FAILED(SafeArrayPutElement(psa,&index,&bval[index]))) AfxMessageBox(_T("错误。")); } varChunk.vt =VT_ARRAY|VT_UI1; varChunk.parray=psa; try { m_pRecord->Fields->GetItem("ImageData")->AppendChunk(varChunk); } catch (_com_error e) { AfxMessageBox(_T("错误。")); } ::VariantClear(&varChunk); ::SafeArrayDestroyData(psa); if (uIsRead<ChunkSize)break; } f.Close(); } INT CDlgTest::GetEncoderClsid(const WCHAR* format, CLSID* pClsid) { UINT num = 0; // number of image encoders UINT size = 0; // size of the image encoder array in bytes ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size); if(size == 0) return -1; // Failure pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); if(pImageCodecInfo == NULL) return -1; // Failure GetImageEncoders(num, size, pImageCodecInfo); for(UINT j = 0; j < num; ++j) { if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) { *pClsid = pImageCodecInfo[j].Clsid; free(pImageCodecInfo); return j; // Success } } free(pImageCodecInfo); return -1; // Failure }
至此就实现了存储图片和从数据库中把图片下载到本地的功能。
精彩图集
精彩文章