读取和写入 BMP 文件

Posted

技术标签:

【中文标题】读取和写入 BMP 文件【英文标题】:Reading and Writing to BMP file 【发布时间】:2015-04-27 10:24:54 【问题描述】:

我是 C++ 和编程新手。我有以下有缺陷的代码可以从 BMP 文件中读取并写入另一个 BMP 文件。我不想使用任何外部库。

我有一个 800kb 24 位 bmp 文件。我的bmp.bmp。将尝试将其上传到保管箱。

`#include <iostream>
#include <conio.h>
#include <fstream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;


unsigned char* editing(char* filename)  

    int i;
int j;
FILE* mybmpfilespointer;
mybmpfilespointer = fopen(filename, "rb");
unsigned char headerinfo[54];
fread(headerinfo, sizeof(unsigned char), 54, mybmpfilespointer); // read the 54-byte header size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

// extract image height and width from header
int width = *(int*)&headerinfo[18];
int height = *(int*)&headerinfo[22];

int size = 3 * width * height;
unsigned char* imagesdata = new unsigned char[size]; // allocate 3 bytes per pixel
fread(imagesdata, sizeof(unsigned char), size, mybmpfilespointer); // read the rest of the imagesdata at once

// display image height and width from header
 cout << " width:" << width << endl;
cout << " height:" << height << endl;

ofstream arrayfile("bmpofstream.bmp"); // File Creation 

for(int a = 0; a < 53; a++) //bgr to rgb

    arrayfile << headerinfo[a];


for(int k=0; k<size; k++)

    arrayfile<<imagesdata[k]<<endl; //Outputs array to file

arrayfile.close();

delete[] mybmpfilespointer;
delete[] imagesdata;
fclose(mybmpfilespointer);
return imagesdata;
return headerinfo;




int main()


FILE* mybmpfilespointer = fopen("mybmp.bmp", "rb");
if (mybmpfilespointer)


     editing("mybmp.bmp");
 
 else
 
     cout << "Cant Read File";
 

`

如您所见,我从 mybmp.bmp 中读取了 819680 字节

按原样写入 bmpofstream.bmp

但不知何故,生成的文件恰好是 mybmp 大小的 3 倍,大约 2460826 字节。

我从 mybmp 文件中读取标题为 headerinfo。 和 mybmp 中的数据为 imagesdata

当我写入 bmpofstream.bmp 这些数组时,它是一个混乱的 bmp 文件。

1)我猜文件大小的增加与读取单个像素并将它们写入 3 次或其他东西有关,但无法弄清楚。为什么会这样?

2) 一旦我弄清楚如何按原样读写这个文件,我就想修改它。所以我不妨现在问这个:

我想修改这张图片,以便我可以将每个像素的值增加 50,这样最终会得到一张更暗的图片。我可以直接这样做吗:

 for(j = 0; j < size; j++) 
  
     imagesdata[j]=imagesdata[j]+50;
   

谢谢。

【问题讨论】:

【参考方案1】:

我建议看看一些现有的库,即使你想自己编写代码,你也可以学到很多东西。参见例如 libbmp 源代码, https://code.google.com/p/libbmp/

【讨论】:

【参考方案2】:

试试这个

#include <iostream>
#include <conio.h>
#include <fstream>
#include <vector>
#include <iterator>

void editing( char* filename )

    std::ifstream input( filename, std::ios::binary );

    if( !input.is_open() )
    
        std::cout << "Can`t open file" << std::endl;
        return;
    

    // copies all data into buffer
    std::vector<char> buffer( ( std::istreambuf_iterator<char>( input ) ), ( std::istreambuf_iterator<char>() ) );
    input.close();

    std::vector<char> headerinfo;
    
        auto it = std::next( buffer.begin(), 54 );
        std::move( buffer.begin(), it, std::back_inserter( headerinfo ) );
        buffer.erase( buffer.begin(), it );
    
    // extract image height and width from header
    int width = *reinterpret_cast<int*>( (char*)headerinfo.data() + 18 );
    int height = *reinterpret_cast<int*>( (char*)headerinfo.data() + 22 );

    int size = 3 * width * height;


    std::vector<char> imagesdata;
    
        auto it = std::next( buffer.begin(), size );
        std::move( buffer.begin(), it, std::back_inserter( imagesdata ) );
        buffer.erase( buffer.begin(), it );
    
    // display image height and width from header
    std::cout << " width:" << width << std::endl;
    std::cout << " height:" << height << std::endl;

    // paste your code here 
    // ...
    std::ofstream arrayfile( "bmpofstream.bmp" ); // File Creation 

    std::ostream_iterator<char> output_iterator( arrayfile );
    std::copy( headerinfo.begin(), headerinfo.end(), output_iterator ); // write header to file
    std::copy( imagesdata.begin(), imagesdata.end(), output_iterator ); // write image data to file


int main(int argc, char**argv)

    editing( argv[1] );

【讨论】:

你能解释一下为什么 OP 应该“尝试一下”吗?为什么不解释差异是什么/您更改或修复了什么/这段代码实际做了什么?这有点像,你知道,你从阿姆斯特丹的一个人那里得到一颗药丸,他说,就像,“试试这个,伙计”。你要吞下去吗?

以上是关于读取和写入 BMP 文件的主要内容,如果未能解决你的问题,请参考以下文章

读取 BMP 文件 C++(读取 BMP 标头时出现问题)

在 C++ 中读取 bmp 文件的宽度和高度

C/C++ 旋转 BMP 图像

读取 BMP 标头,打包。读取不正确的值

在 C++ 中读取 .bmp 文件

用c语言读取24位位图bmp文件