C++实现bmp文件的读写

目录

BMP文件格式:

实现步骤:

涉及文件操作函数:

参考代码实现: 


系统头文件中包含BMP位图格式相关结构体类型定义。

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<<"写文件头成功"<

你可能感兴趣的:(数字图像处理,c++,图像处理)