编译环境:vs2019
代码如下:
#include<iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
#pragma pack(push,1)
struct BMPFILEHEADER
{
unsigned short bfType;
unsigned int bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned int bfOffBits;
};
#pragma pack(pop)
struct BITMAPINFOHEADER
{
unsigned long biSize; //本结构所占用字节数 40字节
long biWidth; //位图的宽度,以像素为单位
long biHeight; //位图的高度,以像素为单位
unsigned short biPlanes; //目标设备的级别,必须为1
unsigned short biBitCount; //每个像素所需的位数,必须是1(双色)、
//4(16色)、8(256色)或24(真彩色)之一
unsigned long biCompression; //位图压缩类型,必须是 0(BI_RGB不压缩)、
//1(BI_RLE8压缩类型)
//2(BI_RLE压缩类型)之一
unsigned long biSizeImage; //位图的大小,以字节为单位
long biXPelsPerMeter; //位图水平分辨率,每米像素数
long biYPelsPerMeter; //位图垂直分辨率,每米像素数
unsigned long biClrUsed; //位图实际使用的颜色表中的颜色数
unsigned long biClrImportant; //位图显示过程中重要的颜色数
};
unsigned char** ReadBMP(const char* filename, BMPFILEHEADER& fh, BITMAPINFOHEADER& ih)
{
FILE* fp = NULL;
fopen_s(&fp, filename, "rb");
unsigned char** data = NULL;
//读取文件头、信息头
fread(&fh, sizeof(fh), 1, fp);
fread(&ih, sizeof(ih), 1, fp);
data = new unsigned char* [ih.biHeight];//相当于data[ih.biheight][ih.biwidth*3];
for (int i = 0; i < ih.biHeight; i++)
{
data[i] = new unsigned char[ih.biWidth*3];
for (int j = 0; j < ih.biWidth * 3; j++)
{
fread(&data[i][j], 1, 1, fp);
}
}
return data;
fclose(fp);
}
void WriteBMP(const char* filename, unsigned char** data, BMPFILEHEADER fh, BITMAPINFOHEADER ih)
{
FILE* fp2 = NULL;
fopen_s(&fp2, filename, "wb");
fwrite(&fh, sizeof(fh), 1, fp2);
fwrite(&ih, sizeof(ih), 1, fp2);
for (int i = 0; i < ih.biHeight; i++)
{
fwrite(data[i], ih.biWidth * 3, 1, fp2);
}
}
unsigned char ** Grey(unsigned char** data,BMPFILEHEADER fh, BITMAPINFOHEADER ih)
{
//修改像数值,取平均值
for (int i = 0; i < ih.biHeight; i++)
{
for (int j = 1; j < ih.biWidth * 3; j += 2)
{
data[i][j] = (data[i][j - 1] + data[i][j] + data[i][j + 1]) / 3;
}
for (int j = 0; j < ih.biWidth * 3; j += 2)
{
if (j == ih.biWidth * 3 - 1)
{
data[i][j] = data[i][j - 1];
break;
}
data[i][j] = data[i][j + 1];
}
}
WriteBMP("grey.bmp", data, fh, ih);
return data;
}
void FlipImageUpDown(unsigned char** d, BMPFILEHEADER fh, BITMAPINFOHEADER ih)
{
unsigned char ** data = new unsigned char* [ih.biHeight];//相当于data[ih.biheight][ih.biwidth*3];
for (int i = 0; i < ih.biHeight; i++)
{
data[i] = new unsigned char[ih.biWidth * 3];
for (int j = 0; j < ih.biWidth*3; j++)//重新写入数据
{
data[i][j] = d[i][j];
}
}
for (int i = 0; i < ih.biHeight / 2; i++)
{
unsigned char* temp;
temp = data[i];
data[i] = data[ih.biHeight - i - 1];
data[ih.biHeight - i - 1] = temp;
}
WriteBMP("up.bmp", data, fh, ih);
for (int i = 0; i < ih.biHeight; i++)
{
delete[]data[i];
}
delete[]data;
}
void FlipImageLeftRight(unsigned char** d,BMPFILEHEADER fh, BITMAPINFOHEADER ih)
{
unsigned char** data = new unsigned char* [ih.biHeight];//相当于data[ih.biheight][ih.biwidth*3];
for (int i = 0; i < ih.biHeight; i++)
{
data[i] = new unsigned char[ih.biWidth * 3];
for (int j = 0; j < ih.biWidth * 3; j++)//重新写入数据
{
data[i][j] = d[i][j];
}
}
for (int i = 0; i < ih.biHeight; i++)
{
for (int j = 0; j < ih.biWidth * 3/2; j++)
{
unsigned char temp;
temp = data[i][j];
data[i][j] = data[i][ih.biWidth * 3 - j - 1];
data[i][ih.biWidth * 3 - j - 1] = temp;
}
}
WriteBMP("left.bmp", data, fh, ih);
for (int i = 0; i < ih.biHeight; i++)
{
delete[]data[i];
}
delete[]data;
}
void ResizeImage(unsigned char **d,BMPFILEHEADER fh,BITMAPINFOHEADER ih)
{
unsigned char** data = new unsigned char* [ih.biHeight];//相当于data[ih.biheight][ih.biwidth*3];
for (int i = 0; i < ih.biHeight/2; i++)
{
data[i] = new unsigned char[ih.biWidth * 3];
for (int j = 0; j < ih.biWidth * 3/2; j++)//重新写入数据
{
data[i][j] = d[2*i][2*j];
}
}
ih.biWidth /= 2;
ih.biHeight /= 2;
ih.biSizeImage /= 4;
WriteBMP("resize.bmp",data, fh, ih);
for (int i = 0; i < ih.biHeight; i++)
{
delete[]data[i];
}
delete[]data;
}
int main(int argc, char* argv[])
{
BMPFILEHEADER fh;
BITMAPINFOHEADER ih;
unsigned char** data = NULL;
data = ReadBMP("Fruits.bmp", fh, ih);
// Grey(data, fh,ih);
data =Grey(data, fh, ih);
WriteBMP("Fruits2.bmp", data, fh, ih);
FlipImageUpDown(data, fh, ih);
FlipImageLeftRight(data, fh, ih);
ResizeImage(data, fh, ih);
cout << "运行成功" << endl;
return 0;
}