//bmp.h
#ifndef _BMP_H_
#define _BMP_H_
#pragma pack (1)
typedef struct tagBITMAPFILEHEADER
{
char bfType[2]; //文件类型,在WINDOWS系统中为BM
long bfSize; //文件大小
short bfReserved1; //保留,设置为0
short bfReserved2; //保留,设置为0
long bfOffBits; //实际图形数据的偏移量
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER
{
long biSize; //位图信息头所需字节数,WINDWS系统中为40字节
long biWidth; //图像宽度
long biHeight; //图像高度
short biPlanes; //为目标设备说明位面数,其值为1
short biBitCount; //每个像素所占位数,单色为1,16色为4,256色为8,24真彩色为24
long biCompression; //压缩类型,BMP为0
long biSizeImage; //图像大小,无压缩设为0
long biXPelsPerMeter; //水平分辨率
long biYPelsPerMeter; //垂直分辨率
long biClrUsed; //位图使用的颜色数
long biClrImportant; //重要的颜色数
} BITMAPINFOHEADER;
typedef struct tagRGBQUAD
{
unsigned char rgbBlue; //指定蓝色强度
unsigned char rgbGreen; //指定绿色强度
unsigned char rgbRed; //指定红色强度
unsigned char rgbReserved; //保留,设为0
} RGBQUAD;
extern unsigned char *pBmpBuf;//读入图像数据的指针
extern long bmpWidth;//图像的宽
extern long bmpHeight;//图像的高
extern RGBQUAD *pColorTable;//颜色表指针
extern int biBitCount;//图像类型,每像素位数
extern int lineByte;
extern bool readBmp(char *);
extern bool saveBmp(char *, unsigned char *, int, int, int, RGBQUAD *);
#endif
//read.c
#include <stdio.h>
#include "bmp.h"
bool readBmp(char *bmpName)
{ // 以二进制读方式打开指定的图像文件
FILE *fp=fopen(bmpName,"rb");
if(fp==0) return 0;
//定义位图文件头结构变量,读取位图文件头进内存,存放在变量file中
BITMAPFILEHEADER file;
fseek(fp,0,0);
fread(&file,sizeof(BITMAPFILEHEADER),1,fp);
printf("%.2s ",file.bfType);
long bfSize=file.bfSize;
short bfReserved1=file.bfReserved1;
short bfReserved2=file.bfReserved2;
long bfOffBits=file.bfOffBits;
//定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中
BITMAPINFOHEADER head;
fread(&head,sizeof(BITMAPINFOHEADER),1,fp);
bmpWidth=head.biWidth;
bmpHeight=head.biHeight;
biBitCount=head.biBitCount;
//定义变量,计算图象每行像素所占的字节数
lineByte=(bmpWidth*biBitCount/8+3)/4*4;
//灰度图象有颜色表,且颜色表表项为256
if(biBitCount==8)
{//申请颜色表所需要的空间,读颜色表进内存
pColorTable=new RGBQUAD[256];
fread(pColorTable,sizeof(RGBQUAD),256,fp);
}
//申请位图数据所需要的空间,读位图数据进内存
pBmpBuf=new unsigned char[lineByte*bmpHeight];
fread(pBmpBuf,1,lineByte*bmpHeight,fp);
//关闭文件
fclose(fp);
return 1;
}
//save.c
#include <stdio.h>
#include "bmp.h"
bool saveBmp(char *bmpName, unsigned char *imgBuf, int width, int height, int biBitCount,
RGBQUAD *pColorTable)
{
//如果位图数据指针为0,则没有数据传入,函数返回
if(!imgBuf)
return 0;
//颜色表大小,以字节为单位,灰度图像颜色表为1024字节,彩色图像颜色表大小为0
int colorTablesize=0;
if(biBitCount==8)
colorTablesize=1024;
//待存储图像数据每行字节数为4的倍数
int lineByte=(width * biBitCount/8+3)/4*4;
//以二进制写的方式打开文件
FILE *fp=fopen(bmpName,"wb+");
if(fp==0) return 0;
//申请位图文件头结构变量,填写文件头信息
BITMAPFILEHEADER file;
file.bfType[0] = 0x42;//bmp类型
file.bfType[1] =0x4D;
//bfSize是图像文件4个组成部分之和
file.bfSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ colorTablesize + lineByte*height;
file.bfReserved1 = 0;
file.bfReserved2 = 0;
//bfOffBits是图像文件前3个部分所需空间之和
file.bfOffBits=54+colorTablesize;
//写文件头进文件
fwrite(&file, sizeof(BITMAPFILEHEADER),1, fp);
//申请位图信息头结构变量,填写信息头信息
BITMAPINFOHEADER head;
head.biBitCount=biBitCount;
head.biClrImportant=0;
head.biClrUsed=0;
head.biCompression=0;
head.biHeight=height;
head.biPlanes=1;
head.biSize=40;
head.biSizeImage=lineByte*height;
head.biWidth=width;
head.biXPelsPerMeter=0;
head.biYPelsPerMeter=0;
//写位图信息头进内存
fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp);
//如果灰度图像,有颜色表,写入文件
if(biBitCount==8)
if(fwrite(pColorTable, sizeof(RGBQUAD),256, fp)!=256)
printf("/nwrite error/n");
else if(biBitCount == 1)
fwrite(pColorTable, sizeof(RGBQUAD), 2, fp);
else if(biBitCount == 4)
fwrite(pColorTable, sizeof(RGBQUAD), 2^4, fp);
//写位图数据进文件
fwrite(imgBuf, height*lineByte, 1, fp);
//关闭文件
fclose(fp);
return 1;
}
//main.c
#include <stdio.h>
#include "bmp.h"
#include "bmp.h"
unsigned char *pBmpBuf;//读入图像数据的指针
long bmpWidth;//图像的宽
long bmpHeight;//图像的高
RGBQUAD *pColorTable;//颜色表指针
int biBitCount;//图像类型,每像素位数
int lineByte;
void main()
{
char readpath[]="1.bmp";
readBmp(readpath);
unsigned char *DataOut;
lineByte=(bmpWidth*3+3)/4*4;
int lineByteOut=(bmpWidth*3+3)/4*4;
DataOut=new unsigned char[lineByteOut*bmpHeight];
int i,j,biBitCountOut=24;
for (i=0;i<bmpHeight;i++)
{
for(j=0;j<bmpWidth;j++)
{
*(DataOut+i*lineByteOut+j*3+0)=255-*(pBmpBuf+i*lineByte+j*3+0);
*(DataOut+i*lineByteOut+j*3+1)=255-*(pBmpBuf+i*lineByte+j*3+1);
*(DataOut+i*lineByteOut+j*3+2)=255-*(pBmpBuf+i*lineByte+j*3+2);
}
}
printf("%d, %d",bmpWidth,biBitCount);
char writePath[]="change.bmp";
saveBmp(writePath,DataOut,bmpWidth,bmpHeight,biBitCountOut,pColorTable);
//清除缓冲区
delete []DataOut;
delete []pColorTable;
}