MFC中BMP图片双显和灰度

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

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

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

浮点算法: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的位图
    }
}
时间: 2024-08-08 01:18:57

MFC中BMP图片双显和灰度的相关文章

MFC 对话框Picture Control(图片控件)中静态和动态显示Bmp图片

最近有同学问我如何实现MFC基于对话框在图片控件中加载图片?其实使用MFC显示图片的方法各种各样,但是还是有些同学不知道怎样显示.以前在<数字图像处理>课程中完成的软件都是基于单文档的程序,这里介绍两种在对话框picthre控件中显示BMP图片的最简单基础的方法. ~~方法可能并不完美,高手忽略,但是提供一种能运行的方法,希望对刚接触这方面知识的同学有所帮助.可能你觉得文章过于简单或者有些过于详细叙述(点到即可我并不反对),但也为哪些入门同学想想,当初自己也是一头雾水. 一.静态显示bmp图片

【转】MFC中png格式图片贴图的实现

原地址:MFC中png格式图片贴图的实现 学vc,正在做五子棋,五子棋中的图片格式都是bmp格式的,所以贴图用CBitmap可以很简单的实现.刚开始也没有在意那么多,今天刚把五子棋做完就兴冲冲的把代码和release版本的exe文件发给我的指导老师看,发现我的文件相当大,所以指导老师给我指出了bmp格式的图片比较占内存,让我寻找一下png格式的贴图. 于是我在网上搜索了大量的资料,看到了有用API OleLoadPicture来加载JPG.GIF格式的图片,但是这种方法不支持png格式,并且GI

MFC对话框显示BMP图片

1.MFC对话框显示BMP图片我们先从简单的开始吧.先分一个类: (一) 非动态显示图片(即图片先通过资源管理器载入,有一个固定ID) (二) 动态载入图片(即只需要在程序中指定图片的路径即可载入) 为方便说明,我们已经建好一个基于对话框的工程,名为Ttest. 对话框类为CTestDlg (一)    非动态载入图片. 方法1.先从最简单的开始,用picture 控件来实现. 步骤: 先在资源里Import一张图片,ID为IDB_BITMAP2 然后在对话框上添加一个picture控件,右键点

VC++使用CImage在内存中Bmp转换Jpeg图片

之前写了一篇<VC++使用CImage在内存中Jpeg转换Bmp图片>,通过CImage实现了在内存中Jpeg转Bmp. 既然Jpeg能转Bmp,那CImage也支持Bmp转Jpeg,与上一篇文章依赖CImage的Load函数相反,Bmp转Jpeg通过Save函数实现: 使用的也是IStream接口的函数重载,具体可以参考MSDN:http://msdn.microsoft.com/zh-cn/library/d06f3fhw.aspx 下面贴出使用CImage在内存中Bmp转换Jpeg的代码

mfc中 控件 对话框 添加颜色 背景图片

1 设置对话框透明 在设置控件颜色中要使用 nCtlColor Contains one of the following values, specifying the type of control: CTLCOLOR_BTN   Button control CTLCOLOR_DLG   Dialog box CTLCOLOR_EDIT   Edit control CTLCOLOR_LISTBOX   List-box control CTLCOLOR_MSGBOX   Message b

VC++使用CImage在内存中Jpeg转换Bmp图片

VC++中Jpeg与Bmp图片格式互转应该是会经常遇到,Jpeg相比Bmp在图片大小上有很大优势. 本文重点介绍使用现有的CImage类在内存中进行转换,不需要保存为文件,也不需要引入第三方库. Libjpeg库在8以后也支持了内存读取和转换,不过使用起来较为麻烦,还需要手动编译,用CImage类完全可以实现,代码更简洁. 实现方法: VC++对Jpeg.Png图片的操作主要使用CImage,相信很多人用过CImage的Load和Save函数从文件读取或保存Jpeg或Png格式的文件,这两个重载

Linux framebuffer显示bmp图片

framebuffer简介     帧缓冲(framebuffer)是Linux为显示设备提供的一个接口,把显存抽象后的一种设备,他允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作.framebuffer是LCD对应的一中HAL(硬件抽象层),提供抽象的,统一的接口操作,用户不必关心硬件层是怎么实施的.这些都是由Framebuffer设备驱动来完成的.     帧缓冲设备对应的设备文件为/dev/fb*,如果系统有多个显示卡,Linux下还可支持多个帧缓冲设备,最多可达32个,分别为/d

【VC++技术杂谈006】截取电脑桌面并将其保存为bmp图片

本文主要介绍如何截取电脑桌面并将其保存为bmp图片. 1. Bmp图像文件组成 Bmp是Windows操作系统中的标准图像文件格式. Bmp图像文件由四部分组成: (1)位图头文件数据结构,包含Bmp图像文件的类型.文件大小等信息. (2)位图信息数据结构,包含Bmp图像的宽.高.压缩类型等信息. (3)颜色表,该部分可选,有些位图需要,有些位图(如24位真彩色位图)不需要. (4)位图数据. 1.1位图头文件数据结构 位图头文件数据结构包含Bmp图像文件的类型.文件大小等信息,占用14个字节.

MFC中的Invalidate、OnDraw、OnPaint函数的作用

MFC中的Invalidate.OnDraw.OnPaint函数的作用 CWnd::Invalidate voidInvalidate( BOOL bErase = TRUE ); 该函数的作用是使 整个窗口客户区无效.窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无效的,需要重绘. 这时Windows会在应用程序的消息队列中放置WM_PAINT消息.MFC为窗口类提供了WM_PAINT的消息处理函数 OnPaint,OnPaint负责