Knowledge Base Nr: 00313 blobbmotl.cpp - http://www.swe-kaiser.de

MFC/OTL: read oracle BLOB and display as Bitmap
mit otl und mfc oracle blob-feld auslesen das eine bmp.datei enthält und anzeigen

  
//ACHTUNG: es werden keine paletten unterstützt!!! d.h. das Bitformat muss RGB => 24 bit sein!

### - blob-feld mit sql-developer füllen:
- in data-tab für tabelle edit-value-dialog für blobfeld öffnen
- image-checkbox für ansicht aktivieren und load-button drücken
- in save-dialog(!!!) datei auswählen
- bild wird noch nicht angezeigt / edit-value-dialog mit ok verlassen
- commit-button drücken
- erst jetzt kann das bild angezeigt werden

### bitmap klasse

class CBitmapObject : public CBaseObject
{
public:
CBitmapObject();
virtual ~CBitmapObject();
...
virtual void OnDraw(CBaseView* pView, CDC* pDC);

VOID* m_lpBits; // bitmap pixels
BITMAPINFO* m_lpBitsInfo; // bitmap header
};

CBitmapObject::CBitmapObject() : CBaseObject()
{
m_lpBits = NULL; // bitmap bits
m_lpBitsInfo = NULL; // bitmap data
}

CBitmapObject::~CBitmapObject()
{
if (m_lpBits)
GlobalFree(m_lpBits);
if (m_lpBitsInfo)
GlobalFree(m_lpBitsInfo);
}

void CBitmapObject::OnDraw(CDC* pDC)
{
if (!m_lpBitsInfo)
return;

::StretchDIBits(pDC->m_hDC, // handle to DC
x, // x-coord of destination upper-left corner
y, // y-coord of destination upper-left corner
w, // width of destination rectangle
h, // height of destination rectangle
0, // x-coord of source upper-left corner
0, // y-coord of source upper-left corner
((*m_lpBitsInfo).bmiHeader).biWidth, // width of source rectangle
((*m_lpBitsInfo).bmiHeader).biHeight, // height of source rectangle
m_lpBits, // bitmap bits
m_lpBitsInfo, // bitmap data
DIB_RGB_COLORS, // usage options
SRCCOPY); // raster operation code
}

### - blob-feld mit otl auslesen


### - bmp-datei (inhalt blob-feld) in CBitmap einlesen


void CHelperFunc::GetBitmapFromBlob(CBitmapObject* pBitmapObj, void* lpFileData)
{
int nFileHeaderSize = sizeof(BITMAPFILEHEADER);

LPBITMAPINFOHEADER bmih = (LPBITMAPINFOHEADER) ((LPBYTE)lpFileData + nFileHeaderSize);
if ((*bmih).biBitCount != 24)
{
AfxMessageBox(theApp.Translate(L"Bitmap hat falsches Format (biBitCount != 24)!"), MB_OK|MB_ICONEXCLAMATION);
return;
}

LPBITMAPINFOHEADER lpBitmap = bmih;

//get pointers into bitmap structures (header, color table and picture bits)
LPBITMAPINFO pBitmapInfo = (LPBITMAPINFO)lpBitmap;
LPBITMAPINFOHEADER pBitmapInfoHeader = (LPBITMAPINFOHEADER)lpBitmap;

//if the picture data uses more then 8 bits per pixel, there's
//no color table to turn into a palette
int nNumberOfColors = 0;

LPBYTE pBitmapPictureData = (LPBYTE)lpFileData + lpBitmap->biSize + nFileHeaderSize + nNumberOfColors*sizeof(RGBQUAD);

//create device independant bitmap
CDC dcScreen;
dcScreen.Attach(::GetDC(NULL));

HBITMAP bitmap = ::CreateDIBitmap(dcScreen.m_hDC, pBitmapInfoHeader, CBM_INIT, pBitmapPictureData,
pBitmapInfo, DIB_RGB_COLORS);
ASSERT(bitmap);

if (pBitmapObj->m_lpBits)
GlobalFree(pBitmapObj->m_lpBits);
if (pBitmapObj->m_lpBitsInfo)
GlobalFree(pBitmapObj->m_lpBitsInfo);

int nSize = pBitmapInfoHeader->biSizeImage;
pBitmapObj->m_lpBits = (VOID*) GlobalAlloc(GMEM_FIXED, nSize);
CopyMemory(pBitmapObj->m_lpBits, pBitmapPictureData, nSize);

nSize = pBitmapInfoHeader->biSize*2;
pBitmapObj->m_lpBitsInfo = (BITMAPINFO*)GlobalAlloc(GMEM_FIXED, nSize);
CopyMemory(pBitmapObj->m_lpBitsInfo, pBitmapInfo, nSize);

int cx = pBitmapInfoHeader->biWidth*6.5f;
int cy = cx * ((float)pBitmapInfoHeader->biHeight / pBitmapInfoHeader->biWidth);
pBitmapObj->SetSize(CSize(cx, cy));

::ReleaseDC(NULL, dcScreen.Detach());
}