码迷,mamicode.com
首页 > 编程语言 > 详细

MFC中BMP图片双显和灰度

时间:2014-12-03 20:52:38      阅读:344      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   os   sp   for   

<一>. Bmp图片双显和灰度原理

     为了方便后续的量化采样处理,这里首先要实现bmp图片双显的功能,即在menu的左边显示原图,把原图的文件头数据和信息头数据保存在全局变量数组中;同时建立一个临时的”picture.bmp”图片(默认保存路径在打开原图的位置),以后的操作对临时的图片进行处理。

什么叫灰度图?任何颜色都有红、绿、蓝三原色组成,假如原来某点的颜色为RGB(RGB),那么,我们可以通过下面几种方法,将其转换为灰度:

      浮点算法:Gray=R*0.3+G*0.59+B*0.11;
      整数方法:Gray=(R*30+G*59+B*11)/100;
      移位方法:Gray =(R*28+G*151+B*77)>>8;
      平均值法:Gray=R+G+B/3;(此程序采用算法);
      仅取绿色:Gray=G
    通过上述任一种方法求得Gray后,将原来的RGB(R,G,B)中的R,G,B统一用Gray替换,形成新的颜色RGB(Gray,Gray,Gray),用它替换原来的RGB(R,G,B)就是灰度图了。

2  改变象素矩阵的RGB值,来达到彩色图转变为灰度图

加权平均值算法:根据光的亮度特性,其实正确的灰度公式应当是

      R=G=B=R*0.299+G*0.587+B0.144;

为了提高速度我们做一个完全可以接受的近似,公式变形如下:R=G=B=(R*3+G*6+B)/10  ;

 

<>.MFC实现双显和灰度

 

第一步:建立标记位

 

1.View.cpp文件中显示函数前建立标记位,即:

 

void CBmpDrawView::ShowBitmap(CDC *pDC,CString BmpName)前添加:
/*****************************************************/
/*   numPicture=0时显示提示错误信息                  */
/*   numPicture=1时显示1张图片在OnFileOpen中定义     */
/*   numPicture=2时显示2张图片和处理在处理函数中定义 */ 
/*****************************************************/

/*****************************************************/
/*   level=0时显示2张图片                            */
/*   level=1时显示灰度图片                           */
/*   level=3时显示图片采样                           */
/*   level=2 4 8 16 32 63时不同量化级量化图片        */ 
/*****************************************************/
int numPicture=0;       //显示图片数 
int level=0;            //显示量化等级

2.在View.h中建立处理图像的副本文件和默认路径:

CBitmap m_bitmaplin;//创建临时位图对象进行处理

CString BmpNameLin; //保存图像的副本文件 原工程中

3.在View.cpp的OnFileOpen文件打开函数中初始化标记变量:

void CBmpDrawView::OnFileOpen()中添加:
if( dlg.DoModal() == IDOK )
    {
        //获取路径 文件名 扩展文件名
        BmpName = dlg.GetPathName();
        BmpNameLin = "picture.bmp";
        
        AfxMessageBox("图片打开成功",MB_OK,0);
        numPicture=1;

        EntName = dlg.GetFileExt(); 
        EntName.MakeLower();    //小写字符串
        Invalidate();
    }

第二步:报错处理

指的是在没有载入图片(numPicture=0)时就按保存按钮,或双显、灰度、量化、采样按钮,就会提示相应的错误提示。因为在打卡图片OnFileOpen函数中令numPicture=1初始化才能显示图片及处理。

在View.cpp中的函数void CBmpDrawView::OnFileSave()中最前面增加代码如下:

//如果没有导入图片直接点击保存 提示信息
    if(numPicture==0)
{
        AfxMessageBox("载入图片后才能保存图片!",MB_OK,0);
         return;
    }

第三步:增加双显菜单

a.将试图切换到ResourceView界面--选中Menu--在IDR_MAINFRAME中添加菜单“显示”--双击它在菜单属性中选择“弹出”

b.在“显示”的子菜单中添加:

双图显示--ID_SHOW_TWO(ID)--默认属性

灰度图片--ID_SHOW_HD(ID)--默认属性

第四步:实现双显

查看--建立类导向(Ctrl+W)--CBmpDrawView(类名)--ID_SHOW_TWO-- COMMAND(Messages)--默认成员函数名。

添加代码:

/*显示2张图片*/
void CBmpDrawView::OnShowTwo() 
{
    // TODO: Add your command handler code here
    //如果没有导入图片直接点击显示2张图片 提示信息
    if(numPicture==0)
    {
        AfxMessageBox("载入图片后才能显示2张图片!");
        return;
    }

    AfxMessageBox("显示两张图片!",MB_OK,0);
    numPicture = 2;              //全局变量=2显示双图、=1显示一图 、=0无图显示
    level=0;                    //level=0双图显示
    Invalidate();               //调用Invalidata()每秒调用一次OnDraw画图
}

第五步:实现灰度图片

查看--建立类导向(Ctrl+W)--CBmpDrawView(类名)--ID_SHOW_HD(ID)-- COMMAND(Messages)--默认成员函数名。

添加代码:

/*灰度图像就是 R=G=B且为三者的1/3 level=1时灰度图像*/
void CBmpDrawView::OnShowHd() 
{
    //如果没有导入图片直接点击灰度 提示信息
    if(numPicture==0)
{
        AfxMessageBox("载入图片后才能灰度图片!",MB_OK,0); return;
    }
    
AfxMessageBox("灰度图像!",MB_OK,0);
FILE *fpo = fopen(BmpName,"rb");
    FILE *fpw = fopen(BmpNameLin,"wb+");
    fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
    fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
    fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    
/*灰度图像处理r=g=b=(r+g+b)/3*/
    int color,red,green,blue;
    for( int i=0; i<m_nWidth*m_nHeight; i++ )
    {
        fread(&red,sizeof(char),1,fpo);
        fread(&green,sizeof(char),1,fpo);
        fread(&blue,sizeof(char),1,fpo);
        color=(red+green+blue)/3;
        red=color; green=color; blue=color;
        fwrite(&red,sizeof(char),1,fpw);
        fwrite(&green,sizeof(char),1,fpw);
        fwrite(&blue,sizeof(char),1,fpw);
    }

    fclose(fpo); fclose(fpw);
    numPicture = 2;
    level=1;
    Invalidate();
}

第六步:添加代码在ShowBitmap显示处理修改

/*显示BMP格式图片 双显灰度功能*/

void CBmpDrawView::ShowBitmap(CDC *pDC, CString BmpName)
{
    
    HBITMAP m_hBitmap;
    m_hBitmap = (HBITMAP) LoadImage(NULL,BmpName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_CREATEDIBSECTION);
    if( m_bitmap.m_hObject ){ m_bitmap.Detach();}
    m_bitmap.Attach(m_hBitmap);
    
    CRect rect;
    GetClientRect(&rect);
    int m_nWindowWidth = rect.right - rect.left;   //计算客户区宽度
    int m_nWindowHeight = rect.bottom - rect.top;  //计算客户区高度
        
    CDC dcBmp;
    if( !dcBmp.CreateCompatibleDC(pDC) )           
return;
    
    BITMAP m_bmp;
    m_bitmap.GetBitmap(&m_bmp); 
    CBitmap *pbmpOld = NULL;
    dcBmp.SelectObject(&m_bitmap);    
    
    if(m_nDrawWidth<650 && m_nDrawHeight<650)
pDC->StretchBlt(0,0,m_nDrawWidth,m_nDrawHeight,&dcBmp,0,0,m_bmp.bmWidth,m_bmp.bmHeight,SRCCOPY);
    else
pDC->StretchBlt(0,0,640,640,&dcBmp,0,0,m_bmp.bmWidth,m_bmp.bmHeight,SRCCOPY);  
    
    dcBmp.SelectObject(pbmpOld);            
    DeleteObject(&m_bitmap);             
    dcBmp.DeleteDC();                      
    
    

/*显示第2张图片*/
    if( numPicture == 2 )
    {
        HBITMAP m_hBitmapChange;
        if(level==0)      //显示2张图
        {
            m_hBitmapChange = (HBITMAP) LoadImage(NULL,BmpName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_CREATEDIBSECTION);
        }
        else if(level==1) //灰度图片
        {
            m_hBitmapChange = (HBITMAP) LoadImage(NULL,BmpNameLin,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_CREATEDIBSECTION);
        }
        
        if( m_bitmap.m_hObject ){ m_bitmap.Detach(); }
        m_bitmap.Attach(m_hBitmapChange);

        CDC dcBmp;
        if( !dcBmp.CreateCompatibleDC(pDC) )       
            return;
        
        BITMAP m_bmp;                                  
m_bitmap.GetBitmap(&m_bmp);            
        CBitmap *pbmpOld = NULL;
        dcBmp.SelectObject(&m_bitmap);         

        /*图片显示调用函数StretchBlt */
        if(m_nDrawWidth<650 && m_nDrawHeight<650)
pDC->StretchBlt(m_nWindowWidth-m_nDrawWidth,0,m_nDrawWidth,m_nDrawHeight,&dcBmp,0,0,m_bmp.bmWidth,m_bmp.bmHeight,SRCCOPY);
        else
pDC->StretchBlt(m_nWindowWidth-640,0,640,640,&dcBmp,0,0,m_bmp.bmWidth,m_bmp.bmHeight,SRCCOPY);  //显示大小为640*640

        dcBmp.SelectObject(pbmpOld);           //恢复临时DC的位图
    }
}

 

 

 

 

 

 

MFC中BMP图片双显和灰度

标签:style   blog   http   io   ar   color   os   sp   for   

原文地址:http://www.cnblogs.com/Qianqian-Dong/p/4140984.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!