关于BMP和EMF的显示问题

来源:互联网 发布:ae2014 mac 破解补丁 编辑:程序博客网 时间:2024/06/05 20:29

问题起源,我的一个项目中会需要显示bmp或者emf(增强型矢量图)格式的的图形,在View中或者Static中。

解决的办法: 

对于emf,一般用如下方法

CRect  rcDC;
//打开emf文件
HENHMETAFILE enhMetaFile;
enhMetaFile
= GetEnhMetaFile(fileName);
//获得矩形显示区域
m_wndPic.GetWindowRect(&rcDC);
ScreenToClient(rcDC);
InvalidateRect(rcDC);

CPaintDC dc(
this);
dc.PlayMetaFile(enhMetaFile,
&rcDC);
DeleteEnhMetaFile(enhMetaFile);

 

对于bmp,有两种方法,第一种适用于CStatic中

 

const DWORD dwViewStyle =    
    SS_BITMAP 
| SS_CENTERIMAGE | WS_CHILD | WS_VISIBLE/* | WS_HSCROLL | WS_VSCROLL*/;

if (!m_wndPic.Create (_T(""),dwViewStyle, rectDummy, &m_wndTabs, 3)
{
    TRACE0(
"Failed to create output view ");
    
return -1;      // fail to create
}

/////这一段用于生成特定style的static//////////或者用CWnd::ModifyStyle()函数修添加其属性 SS_BITMAP | SS_CENTERIMAGE///////////////m_wndPic为CStatic类型控件,CRect  rcDC;

m_wndPic.GetWindowRect(
&rcDC);
HBITMAP hBmp 
= (HBITMAP)::LoadImage(0, fileName, IMAGE_BITMAP, rcDC.Width(), rcDC.Height(), LR_LOADFROMFILE);
m_wndPic.SetBitmap(hBmp);
DeleteObject(hBmp);

 

另一种方法用于一般view绘图

 

if(!picFile.Open(fileName,CFile::modeRead))
{
    AfxMessageBox(_T(
"打开文件错误"));        
}

//读取BMP文件,获得DIB句柄HDIB
hDIB = ReadDIBFile(picFile);

//获得相应位图的调色板
pPal = new CPalette;
if(!CreateDIBPalette(hDIB,pPal))
{
    AfxMessageBox(_T(
"创建调色板失败"));
}


//获得DIB中图像的高宽
LPSTR    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB);
DWORD m_DIBWidth 
= DIBWidth(lpDIB);
DWORD m_DIBHeight 
= DIBHeight(lpDIB);
GlobalUnlock((HGLOBAL)hDIB);

//获得绘制区域矩形,static中
m_wndPic.GetWindowRect(&rcDC);
ScreenToClient(rcDC);
InvalidateRect(rcDC);
//获得DIB矩形域
rcDIB.top = rcDIB.left = 0;
rcDIB.right 
= m_DIBWidth;
rcDIB.bottom 
= m_DIBHeight;
//绘制图形
CPaintDC dc(this);
if(!PaintDIB(dc,&rcDC,hDIB,&rcDIB,pPal))
    AfxMessageBox(_T(
"绘图失败"));

/////////////以下为其中用到的各种函数//////////////////////
HDIB WINAPI COutputBar::ReadDIBFile(CFile &file)
{
    BITMAPFILEHEADER bmfHeader;
    DWORD dwBitsSize;
    HDIB hDIB;
    LPSTR pDIB;
    dwBitsSize
=file.GetLength();

    
if(file.Read((LPSTR)&bmfHeader,sizeof(bmfHeader))!=sizeof(bmfHeader))
    
{
        
return NULL;
    }


    
if(bmfHeader.bfType!=DIB_HEADER_MARKER)
    
{
        
return NULL;
    }


    hDIB
=(HDIB)::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,dwBitsSize);
    
if(hDIB==0)
    
{
        
return NULL;
    }


    pDIB
=(LPSTR)::GlobalLock((HGLOBAL)hDIB);

    
if(file.Read(pDIB,dwBitsSize-sizeof(BITMAPFILEHEADER))!=dwBitsSize-sizeof(BITMAPFILEHEADER))
    
{
        ::GlobalUnlock((HGLOBAL)hDIB);
        ::GlobalFree((HGLOBAL)hDIB);
        
return NULL;
    }


    ::GlobalUnlock((HGLOBAL)hDIB);

    
return hDIB;
}


BOOL WINAPI COutputBar::CreateDIBPalette(HDIB hDIB, CPalette 
*pPal)
{
    LPLOGPALETTE lpPal;

    HANDLE hLogPal;

    HPALETTE hPal
=NULL;
    
int i;


    WORD wNumColors;

    LPSTR lpbi;
    LPBITMAPINFO lpbmi;
    LPBITMAPCOREINFO lpbmc;

    BOOL bWinStyleDIB;
    BOOL bResult
=FALSE;

    
if(hDIB==NULL)
    
{
        
return FALSE;
    }


    lpbi
=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
    lpbmi
=(LPBITMAPINFO)lpbi;
    lpbmc
=(LPBITMAPCOREINFO)lpbi;
    wNumColors
=DIBNumColors(lpbi);

    
if(wNumColors!=0)
    
{
        hLogPal
=::GlobalAlloc(GHND,sizeof(LOGPALETTE)
            
+sizeof(PALETTEENTRY)*wNumColors);
        
if(hLogPal==0)
        
{
            ::GlobalUnlock((HGLOBAL)hDIB);
            
return FALSE;
        }

        lpPal
=(LPLOGPALETTE)::GlobalLock((HGLOBAL)hLogPal);
        lpPal
->palVersion=PALVERSION;
        lpPal
->palNumEntries=(WORD)wNumColors;

        bWinStyleDIB
=IS_WIN30_DIB(lpbi);

        
for(i=0;i<(int)wNumColors;i++)
        
{
            
if(bWinStyleDIB)
            
{
                lpPal
->palPalEntry[i].peRed=lpbmi->bmiColors[i].rgbRed;
                lpPal
->palPalEntry[i].peGreen=lpbmi->bmiColors[i].rgbGreen;
                lpPal
->palPalEntry[i].peBlue=lpbmi->bmiColors[i].rgbBlue;
                lpPal
->palPalEntry[i].peFlags=0;
            }

            
else
            
{
                lpPal
->palPalEntry[i].peRed=lpbmc->bmciColors[i].rgbtRed;
                lpPal
->palPalEntry[i].peGreen=lpbmc->bmciColors[i].rgbtGreen;
                lpPal
->palPalEntry[i].peBlue=lpbmc->bmciColors[i].rgbtBlue;
                lpPal
->palPalEntry[i].peFlags=0;
            }

        }

        bResult
=pPal->CreatePalette(lpPal);
        ::GlobalUnlock((HGLOBAL)hLogPal);
        ::GlobalFree((HGLOBAL)hLogPal);
    }


    ::GlobalUnlock((HGLOBAL)hDIB);
    
return bResult;
}


DWORD WINAPI COutputBar::DIBWidth(LPSTR lpDIB)
{
    LPBITMAPINFOHEADER lpbmi;
    LPBITMAPCOREHEADER lpbmc;

    lpbmi
=(LPBITMAPINFOHEADER)lpDIB;
    lpbmc
=(LPBITMAPCOREHEADER)lpDIB;


    
if(IS_WIN30_DIB(lpDIB))
    
{
        
return lpbmi->biWidth;
    }

    
else
        
return (DWORD)lpbmc->bcWidth;
}


DWORD WINAPI COutputBar::DIBHeight(LPSTR lpDIB)
{
    LPBITMAPINFOHEADER lpbmi;
    LPBITMAPCOREHEADER lpbmc;

    lpbmi
=(LPBITMAPINFOHEADER)lpDIB;
    lpbmc
=(LPBITMAPCOREHEADER)lpDIB;

    
if(IS_WIN30_DIB(lpDIB))
    
{
        
return lpbmi->biHeight;
    }

    
else
    
{
        
return (DWORD)lpbmc->bcHeight;
    }

}


BOOL WINAPI COutputBar::PaintDIB(HDC hDC, LPRECT lpDCRect, HDIB hDIB, LPRECT lpDIBRect, CPalette 
*pPal)
{
    LPSTR lpDIBHdr;
    LPSTR lpDIBBits;
    BOOL  bSuccess
=FALSE;
    HPALETTE hPal
=NULL;
    HPALETTE hOldPal
=NULL;



    
if(hDIB==NULL)
    
{
        
return FALSE;
    }


    lpDIBHdr
=(LPSTR)::GlobalLock((HGLOBAL)hDIB);

    lpDIBBits
=FindDIBBits(lpDIBHdr);


    
if(pPal!=NULL)
    
{
        hPal
=(HPALETTE)pPal->m_hObject;
        hOldPal
=::SelectPalette(hDC,hPal,TRUE);
    }


    ::SetStretchBltMode(hDC,COLORONCOLOR);

    
if(RECTWIDTH(lpDCRect)==RECTWIDTH(lpDIBRect)&&
        RECTHEIGHT(lpDCRect)
==RECTHEIGHT(lpDIBRect))
    
{
        bSuccess
=::SetDIBitsToDevice(hDC,
            lpDCRect
->left,
            lpDCRect
->top,
            RECTWIDTH(lpDCRect),
            RECTHEIGHT(lpDCRect),
            lpDIBRect
->left,
            (
int)DIBHeight(lpDIBHdr)-
            lpDIBRect
->top-
            RECTHEIGHT(lpDIBRect),
            
0,
            (WORD)DIBHeight(lpDIBHdr),
            lpDIBBits,
            (LPBITMAPINFO)lpDIBHdr,
            DIB_RGB_COLORS);
    }

    
else
    
{
        bSuccess
=::StretchDIBits(hDC,
            lpDCRect
->left,
            lpDCRect
->top,
            RECTWIDTH(lpDCRect),
            RECTHEIGHT(lpDCRect),
            lpDIBRect
->left,
            lpDIBRect
->top,
            RECTWIDTH(lpDIBRect),
            RECTHEIGHT(lpDIBRect),
            lpDIBBits,
            (LPBITMAPINFO)lpDIBHdr,
            DIB_RGB_COLORS,
            SRCCOPY);
    }


    ::GlobalUnlock((HGLOBAL)hDIB);

    
if(hOldPal!=NULL)
    
{    
        ::SelectPalette(hDC,hOldPal,TRUE);
    }


    
return bSuccess;
}


WORD WINAPI COutputBar::DIBNumColors(LPSTR lpbi)
{
    WORD wBitCount;

    
/*    if(IS_WIN30_DIB(lpbi))
    {
    DWORD dwClrUsed;
    dwClrUsed=((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
    if(dwClrUsed!=0)
    {
    return (WORD)dwClrUsed;
    }
    }
    
*/


    
if(IS_WIN30_DIB(lpbi))
    
{
        wBitCount
=((LPBITMAPINFOHEADER)lpbi)->biBitCount;

    }

    
else 
    
{
        wBitCount
=((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
    }



    
switch(wBitCount)
    
{
    
case 1:
        
return 2;
    
case 4:
        
return 16;
    
case 8:
        
return 256;
    
default:
        
return 0;
    }

}


typedef 
struct{
    
int character[13];
}
Sample;

LPSTR WINAPI COutputBar::FindDIBBits(LPSTR lpbi)
{
    
return (lpbi+*(LPDWORD)lpbi+PaletteSize(lpbi));
}


WORD WINAPI COutputBar::PaletteSize(LPSTR lpbi)
{
    
if(IS_WIN30_DIB(lpbi))
    
{
        
return (WORD)(DIBNumColors(lpbi)*sizeof(RGBQUAD));
    }

    
else 
    
{
        
return(WORD)(DIBNumColors(lpbi)*sizeof(RGBTRIPLE));
    }

}


/////////////////////一些需要先期声明的变量等///////////////////////////
//////////.h中///////////////////

DECLARE_HANDLE(HDIB);
#define PALVERSION  0x300
#define IS_WIN30_DIB(lpbi)  ((*(LPDWORD)(lpbi))==sizeof(BITMAPINFOHEADER))
#define RECTWIDTH(lpRect)  ((lpRect->right)-(lpRect->left))
#define RECTHEIGHT(lpRect)  ((lpRect->bottom)-(lpRect->top))
////////////.cpp中/////////////////////////////////////////////
const int nBorderSize = 1;
#define DIB_HEADER_MARKER   ((WORD) ('M' << 8) | 'B')
//////////////如在View中,如下方法获得绘制区域
//   CRect rcDC,rcDIB;
//   this->GetClientRect(rcDC);

原创粉丝点击