关于BMP和EMF的显示问题

问题起源,我的一个项目中会需要显示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);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值