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
}