#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<Windows.h>
#include<cstdio>
#include<cstdlib>
using namespace std;
unsigned char ** ReadBMP(const char* filename, BITMAPFILEHEADER *filehead , BITMAPINFOHEADER *infohead)
{//读取已知文件中的信息存入到二级指针**d中
unsigned char** d;
FILE* fp = fopen(filename, "rb");
if (!fp)
{
printf("文件打开错误");
exit(0);
}
long width, height;
fread(filehead, sizeof(BITMAPFILEHEADER), 1, fp);//读取文件头
fread(infohead, sizeof(BITMAPINFOHEADER), 1, fp);//读取信息头
height = infohead->biHeight ;//读取像素高度
width = infohead->biWidth;//读取像素宽度
// 当读入的图像是"Fruits_480x511.jpg"时,这个图像每行字节数不是4的整数倍,文件里每行都有补零
// 你的这个函数应该能够正确处理这种情况
//补0
if (height % 4 != 0)
{
height = (height * (infohead->biBitCount) / 8 + 3) / 4 * 4;
height = height / 3;
}
if (width % 4 != 0)
{
width = (width* (infohead->biWidth)/ 8 + 3) / 4 * 4;
width = width / 3;
}
//动态开辟内存空间,二维数组
d = new unsigned char* [height];
int i, j;
unsigned char a, b, c;//像素点信息
for (i = 0; i < height; i++)
{
d[i] = new unsigned char[width];
}
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
fread(&a, sizeof(unsigned char), 1, fp);
fread(&b, sizeof(unsigned char), 1, fp);
fread(&c, sizeof(unsigned char), 1, fp);
d[i][j] = (a + b + c) / 3;
}
}
fclose(fp);
return d;
}
void WriteBMP(char *filename,BITMAPFILEHEADER filehead, BITMAPINFOHEADER infohead, unsigned char** p)
{
FILE* fp= fopen(filename, "wb");
if (fp == NULL)
{
printf("文件打开失败");
exit(0);
}
fwrite(&filehead, sizeof(BITMAPFILEHEADER), 1, fp);
fwrite(&infohead, sizeof(BITMAPINFOHEADER), 1, fp);
// fwrite(img, sizeof(RGB), size, pfout);
int height, weight;
height = infohead.biHeight;
weight = infohead.biWidth;
int i, j, k;
for (i = 0; i < height; i++)
{
for (j = 0; j < weight; j++)
{
for (k = 0; k < 3; k++)
fwrite(&p[i][j], sizeof(unsigned char), 1, fp);
}
}
fclose(fp);
/* for (i = 0; i < height; i++)//释放空间
delete[] p[i];
delete p;*/
}
void FlipImageUpDown(unsigned char** d, int rows, int cols)
{
int i, j;
unsigned char **d1=new unsigned char *[rows];
for (i = 0; i < rows; i++)
{
d1[i] = new unsigned char[cols];
}
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
d1[i][j] = d[i][j];
}
}
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
d[i][j] = d1[rows - i - 1][j];
}
}//释放动态分配的
for (i = 0; i < rows; i++)
{
delete[]d1[i];
}
delete []d1;
}
void FlipImageLeftRight(unsigned char** d, int rows, int cols)
{
int i, j;
unsigned char** d1 = new unsigned char* [rows];
for (i = 0; i < rows; i++)
{
d1[i] = new unsigned char[cols];
}
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
d1[i][j] = d[i][j];
}
}
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
d[i][j] = d1[i][cols-j-1];
}
}//释放动态分配
for (i = 0; i < rows; i++)
{
delete[]d1[i];
}
delete []d1;
}
void ResizeImage(unsigned char** d, int rows, int cols)
{
unsigned char **d1 = new unsigned char* [rows / 2];
int i, j;
for (i = 0; i < rows / 2; i++)
{
d1[i] = new unsigned char[cols / 2];
}
for (i = 0; 2 * i < rows; i++)
{
for (j = 0; 2 * j < cols; j++)
{
d1[i][j] = d[i*2][j*2];
}
}
for (i = 0; i < rows / 2; i++)
{
for (j = 0; j < cols / 2; j++)
{
d[i][j] = d1[i][j];
}
}
}
void WriteBMP2(char* filename, BITMAPFILEHEADER filehead, BITMAPINFOHEADER infohead, unsigned char** p)
{
FILE* fp = fopen(filename, "wb");
if (fp == NULL)
{
printf("文件打开失败");
exit(0);
}
infohead.biHeight /= 2;//长宽各变成1/2
infohead.biWidth /= 2;
fwrite(&filehead, sizeof(BITMAPFILEHEADER), 1, fp);
fwrite(&infohead, sizeof(BITMAPINFOHEADER), 1, fp);
// fwrite(img, sizeof(RGB), size, pfout);
int height, weight;
height = infohead.biHeight;
weight = infohead.biWidth;
int i, j, k;
for (i = 0; i < height; i++)
{
for (j = 0; j < weight; j++)
{
for (k = 0; k < 3; k++)
fwrite(&p[i][j], sizeof(unsigned char), 1,fp);
}
}
fclose(fp);
/* for (i = 0; i < height; i++)//释放空间
delete[] p[i];
delete p;*/
}
int main(int argc, char* argv[])
{
// 调用你写的读取BMP图像的函数,读取数据到二维数组
// write your code here
BITMAPFILEHEADER filehead;//文件头
BITMAPINFOHEADER infohead;//信息头
char filename[100];//文件名
cout << "请输入你想要操作的文件名"<<endl;
cin >> filename;
char filename2[100];
cout << "1:上下翻转"<<endl;
cout << "2:左右翻转" << endl;
cout << "3:缩小图片为2分之一" << endl;
cout << "请输入你想要的操作" << endl;
int e;
cin >> e;
unsigned char **a= ReadBMP(filename, &filehead, &infohead);//定义存储信息的数组指针
//ReadBMP(filename,a, &filehead, &infohead);//读取图片中的信息存入到二维数组a中
long height = infohead.biHeight;
long width = infohead.biWidth;
long i, j;
switch (e)
{
case 0:
cin >> filename2;
WriteBMP( filename2,filehead, infohead,a);
cout << "灰度化图片保存完整存入:" << filename2 ;
break;
case 1:
FlipImageUpDown(a, height, width);
cin >> filename2;
WriteBMP(filename2, filehead, infohead, a);
cout << "上下翻转的灰度化图片完整存入::" << filename2 ;
break;
case 2:
FlipImageLeftRight(a, height, width);
cin >> filename2;
WriteBMP(filename2, filehead, infohead, a);
cout << "左右翻转的灰度化图片完整存入::" << filename2;
break;
case 3:
ResizeImage(a, height, width);
cin >> filename2;
WriteBMP2(filename2, filehead, infohead, a);
cout << "缩小为1/2灰度化图片完整存入::" << filename2;
break;
default :
cout << "退出" << endl;
break;
}
return 0;
}
程序结果图片