You are here:   Home >> Win32/MFC >> Simple code to create an EMF or Bitmap file from existed draw code

Simple code to create an EMF or Bitmap file from existed draw code

We often need to create an Enhanced Meta File(EMF) or Bitmap(bmp) from an existed DC draw code. It’s not very difficult but it’s boring to code again and again.
The following is a simple solution, what you need to do is only to implement an IPicDrawer and call DrawEnhMeta or DrawBitmap function.




struct IPicDrawer
{
virtual void GetSize(CSize&) = 0; // It’s the smallest size for EMF
virtual BOOL Draw(CDC*) = 0;
};

BOOL DrawEnhMeta(LPCTSTR lpszFileName, IPicDrawer *pIDrawer)
{
// Draw EMF file, the limitation of DC function refer to MSDN
HDC hDC = ::CreateEnhMetaFile(NULL, lpszFileName, NULL,
_T(“FQ EMF Func\0No Title\0″));
CDC *pDC = CDC::FromHandle(hDC);
if(pDC)
{
CSize sz;
pIDrawer->GetSize(sz);
pDC->FillRect(CRect(0,0,sz.cx,sz.cy), &CBrush(RGB(255,255,255)));
if(pIDrawer->Draw(pDC))
{
HENHMETAFILE hEmf = ::CloseEnhMetaFile(hDC);
if(hEmf)
{
::DeleteEnhMetaFile(hEmf);
return TRUE;
}
else
::DeleteFile(lpszFileName);
}
}
return FALSE;
}

BOOL DrawBitmap(LPCTSTR lpszFileName, IPicDrawer *pIDrawer)
{
// Draw 24 bit true color bitmap file
HANDLE hFile = ::CreateFile(lpszFileName, GENERIC_READ | GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
BOOL bRet = FALSE;
if(hFile)
{
CSize sz;
pIDrawer->GetSize(sz);
BITMAPINFO BmpInfo = {0, }; //
BmpInfo.bmiHeader.biWidth = sz.cx;
BmpInfo.bmiHeader.biHeight = sz.cy;
BmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BmpInfo.bmiHeader.biPlanes = 1;
BmpInfo.bmiHeader.biBitCount = 24; // 24bit
BmpInfo.bmiHeader.biCompression = BI_RGB;
BmpInfo.bmiHeader.biSizeImage = BmpInfo.bmiHeader.biBitCount / 8 *
BmpInfo.bmiHeader.biWidth * BmpInfo.bmiHeader.biHeight;

BITMAPFILEHEADER bmpFileHeader = {0, }; //
bmpFileHeader.bfType = *(WORD*)_T(“BM”);
bmpFileHeader.bfOffBits =
sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmpFileHeader.bfOffBits +=
sizeof(DWORD) – (bmpFileHeader.bfOffBits % sizeof(DWORD));
bmpFileHeader.bfSize = bmpFileHeader.bfOffBits + BmpInfo.bmiHeader.biSizeImage;
//write file header and image information
DWORD dwNum = 0;
bRet = ::WriteFile(hFile, &bmpFileHeader, sizeof(BITMAPFILEHEADER),
&dwNum, NULL);
bRet = bRet && ::WriteFile(hFile, &(BmpInfo.bmiHeader), sizeof(BITMAPINFOHEADER),
&dwNum, NULL);
if(bRet)
{
bRet = FALSE;
//create file mapping
HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE,
0, bmpFileHeader.bfSize, NULL);
if(hMap)
{
// create bitmap object
void *pBits = NULL;
HBITMAP hBMP = ::CreateDIBSection(NULL, &BmpInfo, DIB_RGB_COLORS,
&pBits, hMap, bmpFileHeader.bfOffBits);
if(hBMP)
{
// draw the specified figure to file
CDC memTmpDC;
memTmpDC.CreateCompatibleDC(NULL);
if(memTmpDC.GetSafeHdc())
{
CBitmap *pbmp;
pbmp = CBitmap::FromHandle(hBMP);
if(pbmp)
{
memTmpDC.SelectObject(pbmp);
memTmpDC.FillRect(CRect(0,0,sz.cx,sz.cy), &CBrush(RGB(255,255,255)));
bRet = pIDrawer->Draw(&memTmpDC);
}
}
::DeleteObject(hBMP);
}
::CloseHandle(hMap);
}
}
::CloseHandle(hFile);
}
if(!bRet)
::DeleteFile(lpszFileName);
return bRet;
}

Permalink: Code Library » http://www.ucosoft.com/simple-code-to-create-an-emf-or-bitmap-file-from-existed-draw-code.html

Related Posts

Leave a Reply