预备知识:掌握一些mfc基本的控件用法以及bmp格式的图片的一些内容,当然不知道也无伤大雅。

step1:新建基于对话框的mfc工程

step2:拖控件

然后将PictureControl的ID随便改个名字,必须改(因为默认它为静态的)

step3:读文件

1.

双击打开按钮进行添加事件响应程序,当然在这之前你也可以改变按钮的ID,这样有利于程序的读的顺眼。如果你都双击完了,就别再改ID!!!这里我改成了IDC_OPEN和IDC_SAVE

然后将下列代码复制到时间相应程序中:

CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "位图文件(*.bmp)|*.bmp||");
if (dlg.DoModal() != IDOK) return;
CFile file(dlg.GetPathName(), CFile::modeRead);

这时有可能会出现这种错误:

严重性    代码    说明    项目    文件    行    禁止显示状态
错误    C2664    “CFileDialog::CFileDialog(const CFileDialog &)”: 无法将参数 5 从“const char [24]”转换为“LPCTSTR”    Demo    f:\csdn_demo\demo\demo\demo\demodlg.cpp    162    
可以这么解决:

点击解决方案,然后找到你的项目名称,右键然后点击属性,在常规中将字符集改为使用多字节字符集即可。

这时候你已经可以选择文件了。

2.读文件头与信息头以及像素数据

①文件头:

file.Read(&m_file_Head, sizeof(BITMAPFILEHEADER));  //WORD是一个字,两个字节。

在.h中添加变量m_file_Head的变量声明:

BITMAPFILEHEADER m_file_Head;

有关位图文件头相关:

bfSize = bfOffBits + 图片像素数据的大小(图片的行(还有个四字节对齐问题)*列)。

bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +1024(灰度图像有的颜色表,彩色图像没有)。

②位图信息,包括位图信息头和颜色表

添加以下代码

//读取整个位图信息,包括信息头和颜色表
if (m_pdataInfo != NULL) delete[] m_pdataInfo;  //看看这段内存是否已经用了
m_pdataInfo = (BITMAPINFO*)new BYTE[m_file_Head.bfOffBits - 14];
file.Read(m_pdataInfo, m_file_Head.bfOffBits - 14);//   BITMAPINFOHEADER *pBmih = m_pdataInfo->bmiHeader;//位图信息头指针其实就是位图信息的指针
//int nWidth, nHeight, nBitCount;
m_nWidth = m_pdataInfo->bmiHeader.biWidth;
m_nHeight = m_pdataInfo->bmiHeader.biHeight;
m_nBitCount = m_pdataInfo->bmiHeader.biBitCount;m_nDibWidth = (m_nWidth*m_nBitCount + 31) / 32 *4;//
int nDL = m_nDibWidth * m_nHeight;//字节if (m_pImage != NULL) delete[] m_pImage;m_pImage = new BYTE[nDL];
file.Read(m_pImage, nDL);
file.Close();RedrawWindow();//回调OnPaint,在OnPaint中实现显示
​

然后我们添加变量,添加变量肯定要在类的声明中添加,故打开类视图,双击C×××Dlg,将下列变量定义加入

public:
BYTE *m_pdataInfo;//存位图信息的变量指针变量
int m_nWidth, m_nHeight, m_nBitCount;//从左到右依次是图像宽度,高度,每个像素的位数
BYTE *m_pImage;//存像素数据

考虑到两个都是指针类型的变量,我们就要有销毁和初始化,初始化肯定是在OnInitDialog中,销毁需要自己加。

初始化:双击OnInitDialog,添加如下代码:

m_pdataInfo = NULL;
m_pImage = NULL;

如图所示:

销毁:添加OnDestory函数

再将以下代码贴到OnDestory函数中

if (m_pImage != NULL) delete[] m_pImage;
if (m_pdataInfo != NULL) delete[] m_pdataInfo;

然后我们解释解释这句代码:

m_nDibWidth = (m_nWidth*m_nBitCount + 31) / 32 *4;

这句话就牵扯到四字节对齐问题,它的目的就是保证每行的像素个数都是4的倍数,这句话囊可以将每行不是4的倍数转成每行都是4倍数的像素个数。

假设m_nWidth = 3,8位灰度图像,由于这些全部都是整型,所以(3*8+31)/32*4 = 55/32*4 = 1*4 = 4。

为啥弄成四字节对齐,这牵涉计算机底层了,我们也没必要知道。

3.图像的显示

接下来我们要用到那个框了,先给框加变量。如图所示

在OnPaint中添加:

//显示第一个框if (m_pdataInfo != NULL && m_pImage != NULL){//以上只是读完了图片,下面开始显示,m_ctrlImage就是那个框HDC hdc = m_ctrlImage.GetDC()->GetSafeHdc(); //获得显示的句柄//把图形的哪一部分显示CRect rc;m_ctrlImage.GetWindowRect(&rc);//得到框的信息给到rc中,左上角是原点,m_ctrlImage.ScreenToClient(&rc);//坐标转换,将框的坐标转换到rc中SetStretchBltMode(hdc, STRETCH_HALFTONE); //设置缩放显示模式StretchDIBits(hdc, rc.left, rc.top, rc.Width(), rc.Height(),0, 0, m_nWidth, m_nHeight, m_pImage, (BITMAPINFO *)m_pdataInfo, DIB_RGB_COLORS, SRCCOPY);}

step4:效果演示

step5:bmp图片的保存操作

关键是要区分彩色图片和灰度图片的差别。

双击控件按钮保存添加处理代码,

然后加入以下程序:

// TODO: 在此添加控件通知处理程序代码int nDL = m_nDibWidth * m_nHeight;BITMAPFILEHEADER fileheader;BITMAPINFOHEADER infoHeader;BYTE datacolor[sizeof(RGBQUAD) * 256];BYTE *m_pImage2 = NULL;/*BYTE *m_pImage_t = NULL;if (m_pImage_t != NULL) delete[] m_pImage_t;m_pImage_t = new BYTE[nDL];memcpy(m_pImage_t, m_pImage, nDL);*/CFile bmpFile;CString strFileName;CFileDialog dlg(FALSE, "*.BMP", NULL, NULL, "位图文件(*.BMP)|*.bmp;*.BMP");if (!dlg.DoModal() == IDC_SAVE) return;strFileName = dlg.GetPathName();if (bmpFile.Open(strFileName, CFile::modeCreate | CFile::modeWrite) == 0)return;fileheader.bfType = 0x4d42;fileheader.bfOffBits = m_file_Head.bfOffBits;fileheader.bfSize = m_file_Head.bfOffBits + nDL;fileheader.bfReserved1 = 0;fileheader.bfReserved2 = 0;infoHeader.biSize = sizeof(BITMAPINFOHEADER);infoHeader.biWidth = m_pdataInfo->bmiHeader.biWidth;infoHeader.biHeight = m_pdataInfo->bmiHeader.biHeight;infoHeader.biBitCount = m_pdataInfo->bmiHeader.biBitCount;infoHeader.biClrImportant = m_pdataInfo->bmiHeader.biClrImportant;infoHeader.biClrUsed = m_pdataInfo->bmiHeader.biClrUsed;infoHeader.biCompression = m_pdataInfo->bmiHeader.biCompression;infoHeader.biPlanes = m_pdataInfo->bmiHeader.biPlanes;infoHeader.biSizeImage = nDL;infoHeader.biXPelsPerMeter = m_pdataInfo->bmiHeader.biXPelsPerMeter;infoHeader.biYPelsPerMeter = m_pdataInfo->bmiHeader.biXPelsPerMeter;if (m_pImage2 != NULL) {delete[]m_pImage2;}m_pImage2 = new BYTE[nDL];memcpy(m_pImage2, m_pImage, nDL);bmpFile.Write(&fileheader, 14);bmpFile.Write(&infoHeader,40);if (m_pdataInfo->bmiHeader.biBitCount == 8) {memcpy(datacolor, m_pdataInfo->bmiColors, 1024);bmpFile.Write(datacolor,1024);}bmpFile.Write(m_pImage2, nDL);bmpFile.Close();

再看下效果:

此时桌面会有

VS2015实现bmp格式图片的读取相关推荐

  1. 纯C++实现24位bmp格式图片的读取和修饰

    问题:现有一张bmp图片,要求将它读取到程序中并进行灰度化.水平翻转.模糊.茶色滤镜四种效果的一种,并输出新图片,如下所示: 命令行输入: 其中: 参数1:-b/g/s/r,先后表示blur(模糊), ...

  2. C语言读取和存储bmp格式图片

    开发过程中有时候需要解析bmp数据,下面先简单介绍bmp数据组成,后面附上C语言读取和存储bmp格式图片代码. 典型的位图文件格式通常包含下面几个数据块: BMP文件头:保存位图文件的总体信息. 位图 ...

  3. C语言读取BMP格式图片

    C语言读取BMP格式图片 BMP 维基百科,自由的百科全书 汉漢▼ 位图 扩展名 .bmp 开发者 Microsoft 格式 图像文件格式  本文介绍的是一种图像文件格式. 关于Unicode的第1区 ...

  4. c语言实现pdf显示图片,C语言读取BMP格式图片.pdf

    C语言读取BMP格式图片 C 语言读取BMP 格式图片 以下摘自维基百科,自由的百科全书 BMP 取自位图BitMaP 的缩写,也称为DIB (与设备无关的位图)是微软视窗图形 子系统(Graphic ...

  5. 【数字图像处理】一.MFC详解显示BMP格式图片

    本文主要是讲述<数字图像处理>系列栏目中的第一篇文章.主要详细介绍了BMP图片格式,同时使用C++和MFC显示BMP格式,主要结合自己的<数字图像处理>课程和以前的项目叙述讲解 ...

  6. MFC详解显示BMP格式图片

    本文主要是讲述<数字图像处理>系列栏目中的第一篇文章.主要详细介绍了BMP图片格式,同时使用C++和MFC显示BMP格式,主要结合自己的<数字图像处理>课程和以前的项目叙述讲解 ...

  7. 将BMP 格式图片转换为 JPEG 格式【c语言】

    源码链接: https://blog.csdn.net/qq_44394952/article/details/122587475?spm=1001.2014.3001.5502. 一.任务及目标 利 ...

  8. 将BMP 格式图片转换为 JPEG 格式【c语言源码】

    原理及代码讲解链接: https://blog.csdn.net/qq_44394952/article/details/122587306?spm=1001.2014.3001.5502. 主函数m ...

  9. bmp文件格式_一次性解决CAD转换成BMP格式图片的问题

    关于BMP格式图片,可能很多小伙伴都遇到得比较多,但在这里还是稍微解释一下吧. 它是Windows操作系统中的标准图像文件格式,大家都知道BMP格式的图片都非常大,那是因为它没有经过任何压缩. 当然, ...

最新文章

  1. 对数组中的数字从小到大排序
  2. HarmonyOS之bytrace命令的使用
  3. 通电后第一次开机黑屏_电脑无法开机怎么办,8 种情况的修复方法
  4. Series与DataFrame数据类型操作基础
  5. python进阶07 MySQL
  6. Navicat12及以上才能显示json数据
  7. 深入浅出、通俗易懂的讲解CAN bus
  8. 索尼手机更新android10,索尼XPERIA 10 II终于收到了ANDROID 11更新
  9. iwebshop功能添加——邮箱邀请注册增加积分
  10. Python 四大名著词频画图
  11. 【20考研】考研数学 复习书籍推荐!
  12. Qemu gdb 调试 Liteos realview-pbx-a9 工程
  13. [18调剂]北方民族大学2018年硕士研究生调剂公告
  14. 百度流氓驱动bd0001.sys【多测师】
  15. JUC学习(二):Lock的介绍及使用(实现多线程卖票)
  16. PMP考点梳理大全(考生必看)-6.5
  17. 王坚博士:进入空气稀薄地带
  18. fastboot:刷系统中各个img文件
  19. CRT示波管3SJ1J拆解
  20. 如何给客服人合理安排工作时间

热门文章

  1. 74HC595驱动2位数码管代码实现和注意事项
  2. 想装吗 看看装B大全
  3. EASYRECOVERY_3.3.29包含注册机、都教授数据恢复含注册码
  4. 51 地图基本接口(二)
  5. 15 | SpringBoot + thymeleaf 的登陆页面如何实现国际化
  6. 51nod-生产口罩(拓补排序+DP)by zyz
  7. 基于JavaWeb的血站管理系统
  8. 封装 用户名.计算机,Windows系统自定义封装ISO镜像
  9. EOSRAM终扩容,再谈如何在币圈做“价值投资”!
  10. China Quarantines Mexicans