class CDib : public CObject
{
public:
CDib();
virtual ~CDib();
/**
* Clears all member variables and frees allocated memory.
*/
void DeleteObject();
/**
* Gets the number of bytes per horizontal line in the image.
* \param nWidth the width of the image
* \param nBitsPerPixel number of bits per pixel (color depth)
*/
static int BytesPerLine(int nWidth, int nBitsPerPixel);
/**
* Returns the height of the image in pixels
*/
int GetHeight() const { return m_BMinfo.bmiHeader.biHeight; }
/**
* Returns the width of the image in pixels
*/
int GetWidth() const { return m_BMinfo.bmiHeader.biWidth; }
/**
* Returns the size of the image in pixels
*/
CSize GetSize() const { return CSize(GetWidth(), GetHeight()); }
/**
* Returns the image byte field which can be used to work on.
*/
LPVOID GetDIBits() { return m_pBits; }
/**
* Creates a DIB from a CPictureHolder object with the specified width and height.
* \param pPicture the CPictureHolder object
* \param iWidth the width of the resulting picture
* \param iHeight the height of the resulting picture
*/
void Create32BitFromPicture (CPictureHolder* pPicture, int iWidth, int iHeight);
/**
* Returns a 32-bit RGB color
*/
static COLORREF FixColorRef (COLORREF clr);
/**
* Sets the created Bitmap-image (from Create32BitFromPicture) to the internal
* member variables and fills in all required values for this class.
* \param lpBitmapInfo a pointer to a BITMAPINFO structure
* \param lpBits pointer to the image byte field
*/
BOOL SetBitmap(const LPBITMAPINFO lpBitmapInfo, const LPVOID lpBits);
public:
/**
* Draws the image on the specified device context at the specified point.
* No stretching is done!
* \param pDC the device context to draw on
* \param ptDest the upper left corner to where the picture should be drawn to
*/
BOOL Draw(CDC* pDC, CPoint ptDest);
protected:
HBITMAP m_hBitmap;
BITMAPINFO m_BMinfo;
VOID *m_pBits;
};
CDib::CDib()
{
m_hBitmap = NULL;
DeleteObject();
}
CDib::~CDib()
{
DeleteObject();
}
int CDib::BytesPerLine(int nWidth, int nBitsPerPixel)
{
int nBytesPerLine = nWidth * nBitsPerPixel;
nBytesPerLine = ( (nBytesPerLine + 31) & (~31) ) / 8;
return nBytesPerLine;
}
void CDib::DeleteObject()
{
m_pBits = NULL;
if (m_hBitmap)
::DeleteObject(m_hBitmap);
m_hBitmap = NULL;
memset(&m_BMinfo, 0, sizeof(m_BMinfo));
}
void CDib::Create32BitFromPicture (CPictureHolder* pPicture, int iWidth, int iHeight)
{
CRect r;
CBitmap newBMP;
CWindowDC dc(NULL);
CDC tempDC;
tempDC.CreateCompatibleDC(&dc);
newBMP.CreateDiscardableBitmap(&dc,iWidth,iHeight);
CBitmap* pOldBitmap = tempDC.SelectObject(&newBMP);
r.SetRect(0,0,iWidth,iHeight);
pPicture->Render(&tempDC,r,r);
// Create a 32 bit bitmap
stdex::vector pBits(iWidth * iHeight);
BITMAPINFO bi;
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = iWidth;
bi.bmiHeader.biHeight = iHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = 0;
bi.bmiHeader.biXPelsPerMeter = 0;
bi.bmiHeader.biYPelsPerMeter = 0;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;
SetBitmap(&bi, pBits);
DWORD* pAr = (DWORD*)GetDIBits();
// Copy data into the 32 bit dib..
for(int i=0;i {
for(int j=0;j {
pAr[(i*iWidth)+j] = FixColorRef(tempDC.GetPixel(j,i));
}
}
tempDC.SelectObject(pOldBitmap);
}
BOOL CDib::SetBitmap(const LPBITMAPINFO lpBitmapInfo, const LPVOID lpBits)
{
DeleteObject();
if (!lpBitmapInfo || !lpBits)
return FALSE;
HDC hDC = NULL;
DWORD dwBitmapInfoSize = sizeof(BITMAPINFO);
memcpy(&m_BMinfo, lpBitmapInfo, dwBitmapInfoSize);
hDC = ::GetDC(NULL);
if (!hDC)
{
DeleteObject();
return FALSE;
}
m_hBitmap = CreateDIBSection(hDC, &m_BMinfo,
DIB_RGB_COLORS, &m_pBits, NULL, 0);
::ReleaseDC(NULL, hDC);
if (!m_hBitmap)
{
DeleteObject();
return FALSE;
}
DWORD dwImageSize = m_BMinfo.bmiHeader.biSizeImage;
if (dwImageSize == 0)
{
int nBytesPerLine = BytesPerLine(lpBitmapInfo->bmiHeader.biWidth,
lpBitmapInfo->bmiHeader.biBitCount);
dwImageSize = nBytesPerLine * lpBitmapInfo->bmiHeader.biHeight;
}
GdiFlush();
memcpy(m_pBits, lpBits, dwImageSize);
return TRUE;
}
BOOL CDib::Draw(CDC* pDC, CPoint ptDest)
{
if (!m_hBitmap)
return FALSE;
CSize size = GetSize();
CPoint SrcOrigin = CPoint(0,0);
BOOL resVal = FALSE;
resVal = SetDIBitsToDevice(pDC->GetSafeHdc(),
ptDest.x, ptDest.y,
size.cx, size.cy,
SrcOrigin.x, SrcOrigin.y,
SrcOrigin.y, size.cy - SrcOrigin.y,
GetDIBits(), &m_BMinfo,
DIB_RGB_COLORS);
return resVal;
}
COLORREF CDib::FixColorRef(COLORREF clr)
{
int r = GetRValue(clr);
int g = GetGValue(clr);
int b = GetBValue(clr);
return RGB(b,g,r);
}