我有一个RGBA图像文件,我想在C ++中转换为BMP

时间:2017-01-07 15:49:14

标签: visual-c++ bmp rgba

我是解读图像格式的新手。 我已经阅读过有关imagemagick的内容,但是我可以使用其他任何库吗? 或者它非常像读取rgba文件并重新排列数据。任何代码片段? 这里的任何帮助都会有很大的帮助。

编辑:我写了下面的代码将RGBA图像转换为BMP,但输出图像在查看时无效。我可以在这里得到帮助吗? @bRad Gibson IntegerfileToBMP

推荐的帖子
#include <iostream>
#include <fstream>
#include <cstdint>
#include <iterator>
#include <vector>
using namespace std;

typedef unsigned char  BYTE; // 1byte
typedef unsigned short  WORD; // 2bytes uint16_t
typedef unsigned long  DWORD; //4bytes uint32_t
typedef unsigned long int LONG; 

struct BMP
{
    BMP();
    struct
    {
        WORD ID;
        DWORD fileSizeInBytes;
        WORD reserved1;
        WORD reserved2;
        DWORD pixelArrayOffsetInBytes;
    } FileHeader;

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

    struct
    {
        DWORD headerSizeInBytes;
        DWORD bitmapWidthInPixels;
        DWORD bitmapHeightInPixels;
        WORD colorPlaneCount;
        WORD bitsPerPixel;
        CompressionMethod compressionMethod;
        DWORD bitmapSizeInBytes;
        int32_t horizontalResolutionInPixelsPerMeter;
        int32_t verticalResolutionInPixelsPerMeter;
        DWORD paletteColorCount;
        DWORD importantColorCount;
    } DIBHeader;
};

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;
}

int main()
{
    const std::string rgbaFilename = "rgbaFile.rgba";
    const std::string bitmapFilename = "bitmapFile.bmp";

    //Read RGBA file
    ifstream readRGBA(rgbaFilename, ios::binary);

    if(!readRGBA)
        return 0;

    std::vector<char> buffer((
            std::istreambuf_iterator<char>(readRGBA)), 
            (std::istreambuf_iterator<char>()));

    //Construct .bmp
    BMP bmp;
    size_t charCount = buffer.size();

    bmp.DIBHeader.bitmapSizeInBytes = charCount * sizeof( buffer[ 0 ] );
    bmp.FileHeader.fileSizeInBytes = bmp.FileHeader.pixelArrayOffsetInBytes + bmp.DIBHeader.bitmapSizeInBytes;
    bmp.DIBHeader.bitmapWidthInPixels = static_cast< uint32_t >( ceil( (sqrt( (float)charCount ) ) ));
    bmp.DIBHeader.bitmapHeightInPixels = static_cast< uint32_t >( ceil( charCount / static_cast< float >( bmp.DIBHeader.bitmapWidthInPixels ) ) );

    std::ofstream writeBMP( bitmapFilename, std::ofstream::binary );

    if( !writeBMP )
        return 0;

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

1 个答案:

答案 0 :(得分:0)

有许多图像库可以转换图像数据。如您所述,ImageMagick就是这样一个能够将RAW(RGB [A])数据转换为BMP的库。

然而,与许多其他图像格式相比,BMP格式相对简单。 RAW数据可以转换为具有少量代码的BMP,因此如果您希望减少外部依赖性(例如,不使用外部代码),编写自己的BMP序列化代码并不一定能保证集成外部库。

有关向RAW数据读取格式或从RAW数据写入格式的简单示例,请参阅here