![]() |
Multimedia »
General Graphics »
Bitmaps
Intermediate
License: The Code Project Open License (CPOL)
Conversion of Enhanced Metafile to Bitmap and viceversaBy PravarakhyaAn article on conversion of EMF file to Bitmap file format and BMP to EMF |
VC6, VC7, VC7.1Win2K, WinXP, Win2003, MFC, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

I have come across loads of libraries which convert images from one format to other, but most of them are confined to conversion between raster formats like BMP, JPG, GIF etc., This article explains a class which encapsulates the functionality of converting a vector file format (EMF) to raster file format (BMP). Once an EMF is converted to BMP raster file format, it can then be converted to any other format using the freely available libraries like CxImage.
I had this problem of converting an EMF to BMP when I was doing my earlier project. I have searched a lot for help but couldn't find any except that many people asking similar question in discussion groups. I thought I should share this solution with others and wrote my first article to Code project. I hope it will be useful to you.
Using this code is very simple. Just instantiate the class and call the convert function like this:
CConvertEMFToBMP conv;
//call the convert function
BOOL bRet = conv.ConvertEMFToBMP(m_strEMF,m_strBMP,m_chkScale);
ConvertEMFToBMP takes three parameters:
// m_strEMF - path and file name of EMF file to be converted // m_strBMP - path and file name of BMP file // m_chkScale - boolean. If this is false, EMF is converted to // BMP in original size. // If this is true, the image is scaled to preset size // in the code (explained below)
CConvertEMFToBMP conv;
//call the convert function
BOOL bRet = conv.ConvertEMFToBMP("D:\temp\Sample.emf",
"D:\temp\sample.bmp",false);
CConvertEMFToBMP conv;
//call the convert function
BOOL bRet = conv.ConvertBMPToEMF(m_strBMP,m_strEMF);
ConvertBMPToEMF takes two paramters:
m_strBMP - path and file name of BMP file to be converted
m_strEMF - path and file name of EMF file
CConvertEMFToBMP conv;
//call the convert function
BOOL bRet = conv.ConvertBMPToEMF("D:\temp\Sample.bmp",
"D:\temp\sample.emf",false);
ConvertEMFToBMP converts an EMF to Bitmap by playing the metafile in the MemoryDC and then getting the DIB bits and storing them in the bitmap format. To get the memory DC, an invisible window is created and destroyed at the end of conversion. alternatively, the source code can be modified to take the hwnd to the ConvertEMFToBMP function. The scale image option scales the image to a fixed size #defined in the source code. This can also be modified so as to scale as per the user passed parameter. I have used only API functions so as to make the code light avoiding the MFC DLLs. The following is the step by step explanation of core logic of conversion.
//Create an invisible window HWND hWnd = CreateWindow("#32770","NULL",~WS_VISIBLE,0,0, 100,100,NULL,NULL,NULL,0);
//Get the DC of the Window HDC dc = ::GetDC(hWnd);
//Get the Handle from the enhanced metafile hemf = ::GetEnhMetaFile(strFileName); // Get the header from the enhanced metafile. ZeroMemory( &emh, sizeof(ENHMETAHEADER) ); emh.nSize = sizeof(ENHMETAHEADER); if( GetEnhMetaFileHeader( hemf, sizeof( ENHMETAHEADER ), &emh ) == 0 ) { DeleteEnhMetaFile( hemf ); return FALSE; }
//Declare variables for calculation of metafile rect RECT rect; float PixelsX, PixelsY, MMX, MMY; float fAspectRatio; long lWidth,lHeight; // Get the characteristics of the output device. PixelsX = (float)GetDeviceCaps( dc, HORZRES ); PixelsY = (float)GetDeviceCaps( dc, VERTRES ); MMX = (float)GetDeviceCaps( dc, HORZSIZE ); MMY = (float)GetDeviceCaps( dc, VERTSIZE ); // Calculate the rect in which to draw the metafile based on the // intended size and the current output device resolution. // Remember that the intended size is given in 0.01 mm units, so // convert those to device units on the target device. rect.top = (int)((float)(emh.rclFrame.top) * PixelsY / (MMY*100.0f)); rect.left = (int)((float)(emh.rclFrame.left) * PixelsX / (MMX*100.0f)); rect.right = (int)((float)(emh.rclFrame.right) * PixelsX / (MMX*100.0f)); rect.bottom = (int)((float)(emh.rclFrame.bottom) * PixelsY / (MMY*100.0f)); //Calculate the Width and Height of the metafile lWidth = (long)((float)(abs(rect.left - rect.right))); lHeight =(long)((float)(abs(rect.top-rect.bottom )));
fAspectRatio = (float)lWidth/(float)lHeight; if(bScaleImage) //If miniature option is ON, change //the width and height accordingly { if(fAspectRatio > 1 ) //width is more than height { //Make width as constant and calculate Height lWidth = X_MINIATUREFRAME; lHeight = (long)((float)Y_MINIATUREFRAME / fAspectRatio); } else //width is less than height(or equal to height) { //Make Height as constant and calculate Width lHeight = Y_MINIATUREFRAME; lWidth = (long)((float)X_MINIATUREFRAME * fAspectRatio); } }
memDC=::CreateCompatibleDC(dc);
bitmap = ::CreateCompatibleBitmap(dc,lWidth,lHeight);
::SelectObject(memDC,bitmap);
SetBackColorToWhite(memDC);
PlayEnhMetaFile(memDC,hemf,&rect);
DWORD dwRet = GetLastError();
HPALETTE pal;
if( GetDeviceCaps(dc,RASTERCAPS) & RC_PALETTE )
{
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries =
GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry );
// Create the palette
pal = ::CreatePalette(pLP );
delete[] pLP;
}
HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, pal );
WriteDIB((char*)strBMPFile, hDIB );
DeleteEnhMetaFile( hemf );
::DestroyWindow(hWnd);
hBmp = (HBITMAP*)::LoadImage(NULL,pszBMPFile,IMAGE_BITMAP,0,0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);
BITMAP structure to get the bmp's height and width GetObject(hBmp, sizeof(BITMAP), &bm );
hdcMem =::CreateCompatibleDC(GetDC(NULL));
SelectObject(hdcMem, hBmp);
HDC emfdc = CreateEnhMetaFile(hdcMem, pszEMFFile, NULL,
"Created by Pravarakhya");
BitBlt(emfdc,0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
::CloseEnhMetaFile(emfdc);
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 23 Oct 2003 Editor: Chris Maunder |
Copyright 2003 by Pravarakhya Everything else Copyright © CodeProject, 1999-2009 Web16 | Advertise on the Code Project |