目录
BMP文件格式:
实现步骤:
涉及文件操作函数:
参考代码实现:
数据段名称 | 大小(Byte) | ||
head | 1.位图文件头 | BITMAPFILEHEADER | 14 |
2.位图信息头 | BITMAPINFOHEADER | 40 | |
3.调色板 | RGBQUAD | 由像素所占位数决定(仅索引图像有) | |
Data | 图像数据 | 由图像尺寸与像素位数决定 |
BMP格式解析参考以下博客:
常见图片文件格式简析 - 走看看 (zoukankan.com)http://t.zoukankan.com/go2bed-p-4097758.html
(7条消息) BMP格式详解_Valineliu的博客-CSDN博客_bmp是什么意思https://blog.csdn.net/u012877472/article/details/50272771?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166342149716782395386740%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166342149716782395386740&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-50272771-null-null.142%5Ev47%5Enew_blog_pos_by_title,201%5Ev3%5Econtrol_1&utm_term=bmp%E6%A0%BC%E5%BC%8F&spm=1018.2226.3001.4187
读:
1.读二进制的方式“rb"打开文件;
2.跳过位图文件头;
3.定义位图信息头结构体变量,从文件流中读取”位图信息头“至信息头结构体变量指针指向的内存块;
4.申请调色板所需空间,从文件流中读取”位图调色板“至调色板结构体指针变量指向的内存块;
5.申请图像数据所需空间,从文件流中读取”图像数据“至图像数据指针变量指向的内存块;
6.关闭文件。
写:
1.以二进制写的方式”wb"打开文件;
2.定义文件头结构体变量,填写文件头信息,写文件头进文件流;
3.定义信息头结构体变量,填写信息头信息,写信息头进文件流;
4.若为索引图象,将颜色表写入文件;
5.写位图数据进文件;
6.关闭文件.
PS:
1.读写图像位图数据时,每行数据的字节数必须为4的整数倍,缺位补齐。
2.索引图像的位图数据为颜色表的索引值。
(在
1. fopen()函数
FILE* fopen (const char* filename, const char* mode);
---------------------------------------------------------------
function : 以某种模式打开指定的文件.
parameter: 1. filename:指向包含要打开的文件名的字符串的指针.
2. mode:指向指定文件打开模式的字符串的指针.
return : 成功,fopen() 函数将返回一个指针,指向控制打开的文件流的 FILE 对象.
失败,fopen() 函数返回一个空指针.
参考链接:C++ fopen()用法及代码示例 - 纯净天空 (vimsky.com)
2. fseek()函数
int fseek(FILE* stream, long offset, int origin);
------------------------------------------------------------------------------------------
function:重定位流(数据流/文件)上的文件内部位置指针
paragram:1.stream :要修改的文件流.
2.offset :从原点位移的偏移量(字节数),正数表示正向偏移,负数表示负向偏移.
3.origin :用作添加到偏移量的参考的位置。它可以具有以下值:
0(SEEK_SET)--文件开头位置;
1(SEEK_CUR)--文件当前位置;
2(SEEK_END)--文件尾。
return :成功返回0,失败返回1.
参考:c++ fseek函数-天道酬勤-花开半夏 (zhangshilong.cn)
3. fread()函数
size_t fread(void * buffer, size_t size, size_t count, FILE * stream)
------------------------------------------------------------------------------------------
function : 从流中读取数据块.
parameter: 1. buffer:它以至少(size * count)个字节的大小指定指向内存块的指针以存储对象.
2. size:它指定每个对象的大小(以字节为单位)。 size_t是无符号整数类型.
3. count:它指定元素的数量,每个元素的大小为字节大小.
4. stream:它指定要从中读取数据的文件流.
return : 函数返回成功读取的对象数.
参考:C++ fread()用法及代码示例 - 纯净天空 (vimsky.com)
4.fwrite()函数
size_t fwrite(const void * buffer, size_t size, size_t count, FILE * stream);
-----------------------------------------------------------------------------
function: 将 count 个对象写入给定的输出流,每个对象的大小为 size 个字节
parameter:1.buffer:指向其内容被写入的内存块的指针;
2.size:每个对象的大小(以字节为单位);
3.count:要读取的对象数;
4.stream:要写入数据的文件流.
return:函数返回成功读取的对象数。如果发生错误,返回值可能小于 count
参考: C++ fwrite()实例讲解 - 码农教程 (manongjc.com)
读:
bool readBmp(char* bmpName)
{
//1.二进制读方式打开指定的图像文件
FILE* fp = fopen(bmpName, "rb");
if (fp == 0){
cout<<"The file "<
写:
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;
//1.以二进制写的方式打开文件
FILE* fp = fopen(bmpName, "wb");
if (fp == 0) return 0;
//2.申请位图文件头结构变量,填写文件头信息
BITMAPFILEHEADER fileHead;
fileHead.bfType = 0x4D42;//bmp类型
//bfSize是图像文件4个组成部分之和
fileHead.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ colorTablesize + lineByte * height;
fileHead.bfReserved1 = 0;
fileHead.bfReserved2 = 0;
//bfOffBits是图像文件前三个部分所需空间之和
fileHead.bfOffBits = 54 + colorTablesize;
//写文件头进文件
fwrite(&fileHead, sizeof(BITMAPFILEHEADER), 1, fp);
//cout<<"写文件头成功"<