/********************************************************************************
这是以C语言对BMP图像进行颜色反转处理,适用于64位电脑操作环境
操作对象为24位的BMP图片,因为24位BMP没有调色板,
故文件头(14字节)+位图信息头(40)后面紧跟着就是图像色彩数据。
*********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef unsigned char BYTE; // 定义BYTE为一个字节的类型
typedef unsigned short WORD; // 定义WORD为两个字节的类型
typedef unsigned int DWORD; // 定义DWORD为四个字节的类型
#pragma pack(2) // 按两个字节对齐
/* BMP文件头结构体,共14字节 */
typedef struct BMP_FILE_HEADER
{
WORD bfType; // 文件标识符,类型
DWORD bfSize; // 文件的大小,字节为单位
WORD bfReserved1; // 保留值,必须设置为0
WORD bfReserved2; // 保留值,必须设置为0
DWORD bfOffset; // 文件头的最后到图像数据位开始的偏移量
} BMPFILEHEADER;
//#pragma pack(pop)
/* 位图信息头,共40字节*/
typedef struct BMP_INFO_HEADER
{
DWORD biInfoSize; // 位图信息头的大小
DWORD biWidth; // 图像的宽度,像素单位
DWORD biHeight; // 图像的高度,像素单位
WORD biPlanes; // 图像的平面数,总为1
WORD biBitCount; // 每个像素的位数,及比特数1、4、8、16、24或32
DWORD biCompression; // 压缩类型
DWORD biImageSize; // 图像的大小,以字节为单位
DWORD biXPelsPerMeter; // 水平分辨率
DWORD biYPelsPerMeter; // 垂直分辨率
DWORD biClrUsed; // 使用的色彩数
DWORD biClrImportant; // 重要的颜色数
} BMPINFOHADER;
/* 自定义的存放颜色数据的结构体 */
typedef struct BMP_BASE
{
unsigned char* buf; //用来存放颜色的数据
int width_x; //宽
int height_y; //高
int deepth; //像素的位数及biBitCount
}BMPBASE;
int main()
{
FILE *in; // 定义一个输入文件指针
FILE *out; // 定义一个输出文件指针
BMPFILEHEADER bmpFileHeader; // 定义一个BMP文件头
BMPINFOHADER bmpInfoHeader; // 定义一个BMP位图信息头
BMPBASE bmp; // 定义一个存储颜色信息
/* 打开原始图片并读取有关数据 */
if((in = fopen("photo.bmp", "rb")) == NULL) //打开图片
{
printf("Cann't open the file!\n");
return 0;
}
//fseek(in, 0, SEEK_SET); //指向文件头
fread(&bmpFileHeader, sizeof(BMPFILEHEADER), 1, in); //读取文件头信息
//fseek(in, sizeof(BMPFILEHEADER), SEEK_SET); //指向位图信息头
fread(&bmpInfoHeader, sizeof(BMPINFOHADER), 1, in); //读位图信息头信息
/* 将原始图片色彩信息存储到Bmpbase */
bmp.width_x = bmpInfoHeader.biWidth; //获取图片宽、高、每个像素所占位数等信息
bmp.height_y = bmpInfoHeader.biHeight;
bmp.deepth= bmpInfoHeader.biBitCount;
int lineByte = (bmp.width_x*bmp.deepth / 8 + 3) / 4 * 4;//定义变量,计算图像每行像素所占字节数
bmp.buf = (unsigned char *)malloc(lineByte*bmp.height_y);//创建一定大小的数组空间存放颜色数据
fread(bmp.buf, 1, lineByte*bmp.height_y, in); //将颜色数据读入数组空间
/* 反转图像颜色 */
int i;
for(i = 0; i < lineByte*bmp.height_y; i++)
{
//printf("%d", bmp.buf[i]);
bmp.buf[i] = 255 - bmp.buf[i];
}
/* 创建新图,并写入信息*/
if((out = fopen("new.bmp", "wb")) == NULL) //打开新文件
{
printf("Cann't creat new file!\n");
return 0;
}
//写文件头进文件
fwrite(&bmpFileHeader, sizeof(BMPFILEHEADER), 1, out);
//写位图信息头进文件
fwrite(&bmpInfoHeader, sizeof(BMPINFOHADER), 1, out);
//写颜色数据进文件
fwrite(bmp.buf, lineByte*bmp.height_y, 1, out);
fclose(in);
fclose(out);
return 0;
}