BMP格式内的数据分为三到四个部分,依次是:
一般的bmp图像都是24位,也就是真彩。每8位为一字节,24位也就是使用三字节来存储每一个像素的信息,三个字节对应存放r,g,b三原色的数据,每个字节的存贮范围都是0-255。那么以此类推,32位图即每像素存储r,g,b,a(Alpha通道,存储透明度)四种数据。8位图就是只有灰度这一种信息,还有二值图,它只有两种颜色,黑或者白。
位图起始位置偏移量 - 54
bmp图片每一行都是4的倍数,不足添加无效位
即一行的字节数等于图片宽度(一行像素点总数)* 像素点占的位数
行字节数 = 位图宽 + ((4 - (位图宽 * 像素点位数 / 8)%4))%4
lineByte = bmp.width_x + ((4-(bmp.width_x*bmp.deepth/8)%4))%4;
#ifndef _BMPFORMAT_H_
#define _BMPFORMAT_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;
#endif
功能将8位bmp图片解析读取并写入到新的文件中
/*********************************************************************
* 处理8位bmp位图
*********************************************************************/
#include
#include
#include
#include "bmpFormat.h"
int main()
{
FILE *in; // 定义一个输入文件指针
FILE *out; // 定义一个输出文件指针
BMPFILEHEADER bmpFileHeader; // 定义一个BMP文件头
BMPINFOHADER bmpInfoHeader; // 定义一个BMP位图信息头
BMPBASE bmp; // 定义一个存储颜色信息
unsigned char *tmp; // 调色板(颜色表)信息缓冲区
int lineByte; // 一行字节数
int biPaletteSize; // 调色板信息大小 /* 打开原始图片并读取有关数据 */
if ((in = fopen("in.bmp", "rb")) == NULL) //打开图片
{
printf("Cann't open the file!\n");
return 0;
}
fread(&bmpFileHeader, sizeof(BMPFILEHEADER), 1, in); //读取文件头信息
fread(&bmpInfoHeader, sizeof(BMPINFOHADER), 1, in); //读位图信息头信息
//读取颜色表信息
biPaletteSize = bmpFileHeader.bfOffset - 54;//BMP文件头信息,共14字节;位图信息头,共40字节
tmp = (unsigned char*)malloc(biPaletteSize);
fread(tmp, biPaletteSize, 1, in);
///将原始图片色彩信息存储到Bmpbase
bmp.width_x = bmpInfoHeader.biWidth; //获取图片宽、高、每个像素所占位数等信息
bmp.height_y = bmpInfoHeader.biHeight;
bmp.deepth = bmpInfoHeader.biBitCount;
lineByte = bmp.width_x + ((4-(bmp.width_x*bmp.deepth/8)%4))%4; //定义变量,计算图像每行像素所占字节数,每行都是4的整数倍,不足使用无效字节填充
bmp.buf = (unsigned char *)malloc(lineByte * bmp.height_y); //创建一定大小的数组空间存放颜色数据
fread(bmp.buf, 1, lineByte * bmp.height_y, in); //将颜色数据读入数组空间
/* 创建新图,并写入信息*/
if ((out = fopen("out.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(tmp, biPaletteSize, 1, out);
//写颜色数据进文件
fwrite(bmp.buf, lineByte * bmp.height_y, 1, out);
#if 0
printf("biPaletteSize:%d\n", biPaletteSize);//颜色表大小
printf("width_x:%d width_y:%d\n", bmp.width_x, bmp.height_y);//图片宽高
printf("lineByte:%d\n", lineByte); //行字节数
printf("bmp.deepth:%d\n", bmp.deepth); //一个像素点占用的位数
#endif
fclose(in);
fclose(out);
free(tmp);
free(bmp.buf);
return 0;
}