读取和写入BMP文件

时间:2015-04-27 10:24:54

标签: c++ fread bmp ofstream

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

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

`#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 中读取的是819680bytes

并按原样写入 bmpofstream.bmp

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

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

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

1)我猜测文件大小的增加与读取单个像素并将它们写入3次或者其他东西有关但却无法解决。为什么你认为这会是?

2)一旦我弄清楚如何读取和写入这个文件,我想修改它。所以我现在不妨问一下:

我想修改这个图像,这样我就可以将每个像素的值增加50,所以这会以更暗的图像结束。我可以直接这样做:

 for(j = 0; j < size; j++) 
  {
     imagesdata[j]=imagesdata[j]+50;
   }
谢谢。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

试试这个

#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] );
}