纯c++读取与显示BMP图片

2019/10/7 给某些网络巨婴的说明

第一,不会配置vs环境的请绕道

第二,不懂字符集区别的请走开

第三,不会定义类的成员变量的请去学习

第四,不会处理编译器错误信息的请去百度

第五,什么都不会只会喷人的必删回复

下列代码全是经过测试的,vs2013正常运行,也许用在一些地方有点小BUG,但是整体功能都是正常的(PS:我不是你长辈,没有义务去帮你一点一点改还要改到你满意为止)

 

 

这是个控制台程序,无论是在VC6.0还是在vs上都能够直接用,这就涉及到纯C++语言的图像处理编程

声明:控制台程序只涉及读取,显示麻烦使用MFC

#include<iostream>
#include<Windows.h>
#include<malloc.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
using namespace std;
void main ()
{
	char fileName[30];                        //定义打开图像名字
	char *buf;                                //定义文件读取缓冲区
	char *p;
	int r,g,b,pix;
	HWND wnd;                                 //窗口句柄
	HDC dc;                                   //绘图设备环境句柄
	FILE *fp;                                 //定义文件指针
	FILE *fpw;                                //定义保存文件指针
    DWORD w,h;                                //定义读取图像的长和宽
    DWORD bitCorlorUsed;                      //定义
    DWORD bitSize;                            //定义图像的大小
    BITMAPFILEHEADER bf;                      //图像文件头
    BITMAPINFOHEADER bi;                      //图像文件头信息
	cout<<"请输入要打开文件的名字:(如:e:\\1.bmp)";
	cin>>fileName;
	if((fp=fopen(fileName,"rb"))==NULL)
	{
	   cout<<"文件未找到!";
	   exit(0);
	}
    fread(&bf,sizeof(BITMAPFILEHEADER),1,fp);//读取BMP文件头文件
    fread(&bi,sizeof(BITMAPINFOHEADER),1,fp);//读取BMP文件头文件信息
	w=bi.biWidth;                            //获取图像的宽
	h=bi.biHeight;                           //获取图像的高
	bitSize=bi.biSizeImage;                  //获取图像的size
	buf=(char*)malloc(w*h*3);                //分配缓冲区大小
	fseek(fp,long(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)),0);//定位到像素起始位置
	fread(buf,1,w*h*3,fp);                   //开始读取数据
	wnd=GetForegroundWindow();               //获取窗口句柄
	dc=GetDC(wnd);                           //获取绘图设备
	int x=40;
	int y=40;
	p=buf;
	for(int j=0;j<h;j++)
	{
		for(int i=0;i<w;i++)
		{
			b=*p++;g=*p++;r=*p++;
			pix=RGB(r,g,b);
			SetPixel(dc,x+i,y+h-j,pix);
		}
	}
	fpw=fopen("LenaSaved.bmp","wb");
	fwrite(&bf,sizeof(BITMAPFILEHEADER),1,fpw);  //写入文件头
	fwrite(&bi,sizeof(BITMAPINFOHEADER),1,fpw);  //写入文件头信息
	p=buf;
	for( j=0;j<h;j++)
	{
		for(int i=0;i<w*3;i++)
		{
			fwrite(p++,1,1,fpw);
		}
	}
	fclose(fpw);
	fclose(fp);
	//return fp;
}

第二次编辑内容:从控制台转向MFC编程,下面的代码可用于单文档和多文档,打开和保存BMP图像

1.需要用到多字节字符集,否则会有报错

2.需要自己在头文件声明几个变量

int iBmpWidth;
int iBmpHeight;
BYTE *pBmpData;
BITMAPINFO *pBmpInfo;

3.需要自己拖一个picture控件,命名IDC_PICTURE

void CMyDIPView::OnOK() 
{
	 //CFileDialog为VC中打开文件对话框类   
BITMAPFILEHEADER bmpHeader;//文件头  
BITMAPINFOHEADER bmpInfo;//信息头  
CFileDialog dlg(TRUE, "*.BMP", NULL, NULL,"位图文件(*.BMP)|*.bmp;*.BMP|",this);  
CFile bmpFile;//记录打开文件      
CString strFileName;//记录选择文件路径  

if (!dlg.DoModal() == IDOK) return;  
strFileName = dlg.GetPathName();   //以只读的方式打开文件  
if(!bmpFile.Open(strFileName, CFile::modeRead|CFile::typeBinary)) return;  
if (bmpFile.Read(&bmpHeader,sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))  
{   AfxMessageBox("read bmp header failed!");   
return;  
}  if (bmpHeader.bfType != 0x4d42)  
{   AfxMessageBox("invalid file type!");   return;  }  
if (bmpFile.Read(&bmpInfo,sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPINFOHEADER)) 
 {   AfxMessageBox("read bmp infor header failed!");  
 return;  }  if (bmpInfo.biBitCount != 24)  
 {  AfxMessageBox("File is not 24 bit.Application doesn't support this kind of file!");  
 return;
 }  
 pBmpInfo = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER)];  
 if (!pBmpInfo)  
 {   
	 AfxMessageBox("memory error!");   
	 return;  
 }      
 //为图像数据申请空间  
 memcpy(pBmpInfo,&bmpInfo,sizeof(BITMAPINFOHEADER));  
 DWORD dataBytes = bmpHeader.bfSize - bmpHeader.bfOffBits;  
 pBmpData = (BYTE*)new char[dataBytes];  
 if (!pBmpData)  
 {  
	 AfxMessageBox("memory error!");   
	 delete pBmpData;   return;  
 }  if (bmpFile.Read(pBmpData,dataBytes) != dataBytes)  
 {   AfxMessageBox("Read bmp data failed!");   
 delete pBmpInfo;   
 delete pBmpData;  
 return;  
 }  
 bmpFile.Close();   
 CWnd *pWnd=GetDlgItem(IDC_PICTURE);//获得pictrue控件窗口的句柄  
 CRect rect;  
 pWnd->GetClientRect(&rect);//获得pictrue控件所在的矩形区域  
 CDC *pDC=pWnd->GetDC();//获得pictrue控件的DC     
 //显示图片  
 pDC->SetStretchBltMode(COLORONCOLOR);   
 StretchDIBits(pDC->GetSafeHdc(),0,0,rect.Width(),rect.Height(),0,0,bmpInfo.biWidth,bmpInfo.biHeight,pBmpData,pBmpInfo,DIB_RGB_COLORS,SRCCOPY);   
 iBmpWidth=bmpInfo.biWidth;                       
 iBmpHeight=bmpInfo.biHeight; // TODO: Add extra validation here
	
	
}

void CMyDIPView::OnSave() 
{
	 BITMAPFILEHEADER bmpf;//文件头  
 BITMAPINFOHEADER bmpi;//信息头  
 int Widthbytes;   
 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::modeReadWrite) == 0)return;
 Widthbytes = (iBmpWidth*3+3)/4*4;//位图对齐,确保为4的倍数   
 /* BITMAPFILEHEADER结构填写 */  
 bmpf.bfType = 0x4d42;  
 bmpf.bfOffBits =sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);  
 bmpf.bfSize = bmpf.bfOffBits + Widthbytes *iBmpHeight;  
 bmpf.bfReserved1 = 0;  
 bmpf.bfReserved2 = 0; 
  /* BITMAPINFOHEADER结构填写 */   
 bmpi.biSize = sizeof(BITMAPINFOHEADER); 
 bmpi.biWidth = iBmpWidth;  
 bmpi.biHeight =iBmpHeight;  
 bmpi.biPlanes = 1;   
 bmpi.biBitCount = 24;//24位  
 bmpi.biCompression = BI_RGB;  
 bmpi.biSizeImage =0;   
 bmpi.biXPelsPerMeter = 0;  
 bmpi.biYPelsPerMeter = 0;  
 bmpi.biClrUsed = 0;  
 bmpi.biClrImportant = 0;     
 bmpFile.Write(&bmpf,sizeof(bmpf));//写文件头;  
 bmpFile.Write(&bmpi,sizeof(bmpi));//写信息头;   
 bmpFile.Write(pBmpData,Widthbytes*iBmpHeight);//写图像数据信息;   
 bmpFile.Close(); 
	// TODO: Add your control notification handler code here
	
}

 

 

 

 

 

 

 

 

  • 19
    点赞
  • 137
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值