C ++:将整数的文本文件转换为BMP格式的位图图像文件 [英] C++: Convert text file of integers into a bitmap image file in BMP format

查看:239
本文介绍了C ++:将整数的文本文件转换为BMP格式的位图图像文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个文本文件由包含2D矩阵的矩阵库保存:

I have a text file being saved by a matrix library containing a 2D matrix as such:

1 0 0 
6 0 4
0 1 1

每个数字用彩色像素表示。我正在寻找一些关于我如何解决这个问题的见解。如果需要更多信息,请不要犹豫。

Where each number is represented with a colored pixel. I am looking for some insight as to how I'd go about solving this problem. If any more information is required, do not hesitate to ask.

编辑:我尝试的另一种方法是: fwrite(& intmatrix,size,1,bmp_ptr); 我传入矩阵指针,似乎没有输出可读的BMP文件。 size 的值当然是 rows * cols ,矩阵的类型是 arma :: Mat< int> 这是来自Armadillo线性代数库的矩阵。

Another approach I've tried is: fwrite(&intmatrix, size,1, bmp_ptr); where I pass in the matrix pointer, which does not seem to output a readable BMP file. The value of size is the rows*cols of course, and the type of matrix is arma::Mat<int> which is a matrix from the Armadillo Linear Algebra Library.

编辑II:读这个表明我的大小应该是行* cols * 4给定的大小行如果我没有弄错,那么关于这一点的任何指导都会很棒。

EDIT II: Reading this indicated that my size should probably be rows*cols*4 given the size of the rows if I am not mistaken, any guidance on this point as well would be great.

推荐答案

这是一个生成文本的应用程序随机整数文件,将它们读回,然后将它们作为(大致正方形)每像素32位.BMP图像写入磁盘。

Here's an app which generates a text file of random integers, reads them back, and writes them to disk as a (roughly square) 32-bit-per-pixel .BMP image.

注意,我做了关于诸如原始文本文件的格式,数字范围等的一些假设,但它们在代码中记录。有了这个工作示例,您应该可以在必要时轻松调整它们。

Note, I made a number of assumptions on things like the format of the original text file, the range of numbers, etc., but they are documented in the code. With this working example you should be able to tweak them easily, if necessary.

// IntToBMP.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <cstdint>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <random>
#include <ctime>
#include <memory>

#pragma pack( push, 1 ) 
struct BMP
{
    BMP();
    struct
    {
        uint16_t ID;
        uint32_t fileSizeInBytes;
        uint16_t reserved1;
        uint16_t reserved2;
        uint32_t pixelArrayOffsetInBytes;
    } FileHeader;

    enum class CompressionMethod : uint32_t {   BI_RGB              = 0x00, 
                                                BI_RLE8             = 0x01,
                                                BI_RLE4             = 0x02,
                                                BI_BITFIELDS        = 0x03,
                                                BI_JPEG             = 0x04,
                                                BI_PNG              = 0x05,
                                                BI_ALPHABITFIELDS   = 0x06 };

    struct
    {
        uint32_t headerSizeInBytes;
        uint32_t bitmapWidthInPixels;
        uint32_t bitmapHeightInPixels;
        uint16_t colorPlaneCount;
        uint16_t bitsPerPixel;
        CompressionMethod compressionMethod;
        uint32_t bitmapSizeInBytes;
        int32_t horizontalResolutionInPixelsPerMeter;
        int32_t verticalResolutionInPixelsPerMeter;
        uint32_t paletteColorCount;
        uint32_t importantColorCount;
    } DIBHeader;
};
#pragma pack( pop )

BMP::BMP()
{
    //Initialized fields
    FileHeader.ID                                   = 0x4d42; // == 'BM' (little-endian)
    FileHeader.reserved1                            = 0;
    FileHeader.reserved2                            = 0;
    FileHeader.pixelArrayOffsetInBytes              = sizeof( FileHeader ) + sizeof( DIBHeader );
    DIBHeader.headerSizeInBytes                     = 40;
    DIBHeader.colorPlaneCount                       = 1;
    DIBHeader.bitsPerPixel                          = 32;
    DIBHeader.compressionMethod                     = CompressionMethod::BI_RGB;
    DIBHeader.horizontalResolutionInPixelsPerMeter  = 2835; // == 72 ppi
    DIBHeader.verticalResolutionInPixelsPerMeter    = 2835; // == 72 ppi
    DIBHeader.paletteColorCount                     = 0;
    DIBHeader.importantColorCount                   = 0;
}

void Exit( void )
{
    std::cout << "Press a key to exit...";
    std::getchar();

    exit( 0 );
}

void MakeIntegerFile( const std::string& integerFilename )
{
    const uint32_t intCount = 1 << 20; //Generate 1M (2^20) integers
    std::unique_ptr< int32_t[] > buffer( new int32_t[ intCount ] ); 

    std::mt19937 rng;
    uint32_t rngSeed = static_cast< uint32_t >( time( NULL ) );
    rng.seed( rngSeed );

    std::uniform_int_distribution< int32_t > dist( INT32_MIN, INT32_MAX );

    for( size_t i = 0; i < intCount; ++i )
    {
        buffer[ i ] = dist( rng );
    }

    std::ofstream writeFile( integerFilename, std::ofstream::binary );

    if( !writeFile )
    {
        std::cout << "Error writing " << integerFilename << ".\n";
        Exit();
    }

    writeFile << buffer[ 0 ];
    for( size_t i = 1; i < intCount; ++i )
    {
        writeFile << " " << buffer[ i ];
    }
}

int _tmain(int argc, _TCHAR* argv[])  //Replace with int main( int argc, char* argv[] ) if you're not under Visual Studio
{
    //Assumption: 32-bit signed integers
    //Assumption: Distribution of values range from INT32_MIN through INT32_MAX, inclusive
    //Assumption: number of integers contained in file are unknown
    //Assumption: source file of integers is a series of space-delimitied strings representing integers
    //Assumption: source file's contents are valid
    //Assumption: non-rectangular numbers of integers yield non-rectangular bitmaps (final scanline may be short)
    //            This may cause some .bmp parsers to fail; others may pad with 0's.  For simplicity, this implementation
    //            attempts to render square bitmaps.

    const std::string integerFilename = "integers.txt";
    const std::string bitmapFilename = "bitmap.bmp";

    std::cout << "Creating file of random integers...\n";
    MakeIntegerFile( integerFilename );

    std::vector< int32_t >integers; //If quantity of integers being read is known, reserve or resize vector or use array

    //Read integers from file
    std::cout << "Reading integers from file...\n";
    {   //Nested scope will release ifstream resource when no longer needed
        std::ifstream readFile( integerFilename );

        if( !readFile )
        {
            std::cout << "Error reading " << integerFilename << ".\n";
            Exit();
        }

        std::string number;
        while( readFile.good() )
        {
            std::getline( readFile, number, ' ' );
            integers.push_back( std::stoi( number ) );
        }

        if( integers.size() == 0 )
        {
            std::cout << "No integers read from " << integerFilename << ".\n";
            Exit();
        }
    }

    //Construct .bmp
    std::cout << "Constructing .BMP...\n";
    BMP bmp;
    size_t intCount = integers.size();
    bmp.DIBHeader.bitmapSizeInBytes = intCount * sizeof( integers[ 0 ] );
    bmp.FileHeader.fileSizeInBytes = bmp.FileHeader.pixelArrayOffsetInBytes + bmp.DIBHeader.bitmapSizeInBytes;
    bmp.DIBHeader.bitmapWidthInPixels = static_cast< uint32_t >( ceil( sqrt( intCount ) ) );
    bmp.DIBHeader.bitmapHeightInPixels = static_cast< uint32_t >( ceil( intCount / static_cast< float >( bmp.DIBHeader.bitmapWidthInPixels ) ) );

    //Write integers to .bmp file
    std::cout << "Writing .BMP...\n";
    {
        std::ofstream writeFile( bitmapFilename, std::ofstream::binary );

        if( !writeFile )
        {
            std::cout << "Error writing " << bitmapFilename << ".\n";
            Exit();
        }

        writeFile.write( reinterpret_cast< char * >( &bmp ), sizeof( bmp ) );
        writeFile.write( reinterpret_cast< char * >( &integers[ 0 ] ), bmp.DIBHeader.bitmapSizeInBytes );
    }

    //Exit
    Exit();
} 

希望这有帮助。

这篇关于C ++:将整数的文本文件转换为BMP格式的位图图像文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆