关于BMP和EMF的显示问题

原创 2007年09月26日 11:11:00

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

虚拟打印的实现-EMF转换成BMP

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://fxh7622.blog.51cto.com/63841/50182 ...
  • wzsy
  • wzsy
  • 2011-11-18 11:42
  • 610

利用opengl将3ds文件导入场景并显示,然后保存这个场景为bmp格式图像,其结果与显示不同,问题出在哪儿了

opengl导入的3ds文件显示是这样的 而当我保存这个显示的场景为bmp图像时结果却变成了这个样子: 我写的bmp文件头文件还有写入如下,有什么问题么? void saveBmp(const ...

【matlab】matlab读用索引来表示(伪彩色)的bmp图像的格式相关问题

bmp图像的定义:bmp-百度百科 里面这样说到: 典型的BMP图像文件由四部分组成: 1:位图头文件数据结构,它包含BMP图像文件的类型、显示内容等信息; 2:位图信息数据结构,它...

Test,BMP 问题

  • 2011-07-11 10:18
  • 46KB
  • 下载

关于用FFMPEG截取视频图像保存为BMP图像颠倒及颜色不正常的问题

ffmpeg-tutorial01就是将一个视频中的图像截取并保存为PMG的程序,稍作修改可将图像保存为BMP格式,程序代码如下: // tutorial01.c // Code based ...

用VC6.0调用C语言来读取BMP文件所遇到字节不对齐的问题解决方案

今天自己在测试用C语来读取.BMP文件的时候,自己先去了解BMP文件的结构。BMP文件主要由位图信息头、位图信息数据、调色板组成。具体的数据结构如下: /* 定义WORD为两个字节的类型 */ typ...

BMP基本读取的相关问题

最近一直在写有关BMP文件读写的相关内容,期间遇到不少问题,现在终于算是告一段落。 1.关于BMP的格式,在百度百科上有很详细的介绍http://baike.baidu.com/view/18948...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)