Getting RGB values for each pixel from a 24bpp Bitmap for conversion to GBA format in C

后端 未结 8 1533
南方客
南方客 2020-12-16 08:52

I want to read the RGB values for each pixel from a .bmp file, so I can convert the bmp into a format suitable for GBA (GameBoy Advance).

I

8条回答
  •  再見小時候
    2020-12-16 09:37

    I did a bit of testing and extended Patrice's program a bit. I'm not a good C programmer, so all credit goes to him and my parts aren't as elegant as his - sorry for that.

    Warning: huge source code ahead.

    #include 
    #pragma pack(2)
    
    
    typedef struct
    {
        char signature[2];
        unsigned int fileSize;
        unsigned int reserved;
        unsigned int offset;
    } BmpHeader;
    
    typedef struct
    {
        unsigned int headerSize;
        unsigned int width;
        unsigned int height;
        unsigned short planeCount;
        unsigned short bitDepth;
        unsigned int compression;
        unsigned int compressedImageSize;
        unsigned int horizontalResolution;
        unsigned int verticalResolution;
        unsigned int numColors;
        unsigned int importantColors;
    
    } BmpImageInfo;
    
    typedef struct
    {
        unsigned char blue;
        unsigned char green;
        unsigned char red;
        //unsigned char reserved; Removed for convenience in fread; info.bitDepth/8 doesn't seem to work for some reason
    } Rgb;
    
    
    int main( int argc, char **argv ) {
    
        FILE *inFile;
        BmpHeader header;
        BmpImageInfo info;
        Rgb *palette;
        int i = 0;
    
        printf( "Opening file %s for reading.\n", argv[1] );
    
        inFile = fopen( argv[1], "rb" );
        if( !inFile ) {
            printf( "Error opening file %s.\n", argv[1] );
            return -1;
        }
    
        if( fread(&header, 1, sizeof(BmpHeader), inFile) != sizeof(BmpHeader) ) {
            printf( "Error reading bmp header.\n" );
            return -1;
        }
    
        if( fread(&info, 1, sizeof(BmpImageInfo), inFile) != sizeof(BmpImageInfo) ) {
            printf( "Error reading image info.\n" );
            return -1;
        }
    
        if( info.numColors > 0 ) {
            printf( "Reading palette.\n" );
            palette = (Rgb*)malloc(sizeof(Rgb) * info.numColors);
            if( fread(palette, sizeof(Rgb), info.numColors, inFile) != (info.numColors * sizeof(Rgb)) ) {
                printf( "Error reading palette.\n" );
                return -1; // error
            }
        }
    
        printf( "Opening file %s for writing.\n", argv[2] );
        FILE *outFile = fopen( argv[2], "wb" );
        if( !outFile ) {
            printf( "Error opening outputfile.\n" );
            return -1;
        }
        Rgb *pixel = (Rgb*) malloc( sizeof(Rgb) );
        int read, j;
        for( j=0; jred, pixel->green, pixel->blue );
            }
            if( read % 4 != 0 ) {
                read = 4 - (read%4);
                printf( "Padding: %d bytes\n", read );
                fread( pixel, read, 1, inFile );
            }
        }
    
        printf( "Done.\n" );
        fclose(inFile);
        fclose(outFile);
    
        printf( "\nBMP-Info:\n" );
        printf( "Width x Height: %i x %i\n", info.width, info.height );
        printf( "Depth: %i\n", (int)info.bitDepth );
    
        return 0;
    
    }
    

    This program reads out the pixel information stored in the file. It takes the padding into account but only works with bmps with a 24 bits per pixel color depth (If you need other depths, you'll have to customize the Rgb struct). Hope this helps you, but as I said, it's just an extension of Patrice's code.

    Here's a sample output from my testfile:

    $ ./a.out test.bmp out.txt
    Opening file test.bmp for reading.
    Opening file out.txt for writing.
    ------ Row 1
    Pixel 1:   0   0   0
    Pixel 2:   0   0   0
    Pixel 3:   0   0   0
    Pixel 4:   0   0   0
    Pixel 5:   0   0   0
    Padding: 1 bytes
    ------ Row 2
    Pixel 1:   0   0   0
    Pixel 2: 232  33  33
    Pixel 3:   0   0   0
    Pixel 4: 232  33  33
    Pixel 5:   0   0   0
    Padding: 1 bytes
    ------ Row 3
    Pixel 1:   0   0   0
    Pixel 2:   0   0   0
    Pixel 3: 232  33  33
    Pixel 4:   0   0   0
    Pixel 5:   0   0   0
    Padding: 1 bytes
    ------ Row 4
    Pixel 1:   0   0   0
    Pixel 2: 232  33  33
    Pixel 3:   0   0   0
    Pixel 4: 232  33  33
    Pixel 5:   0   0   0
    Padding: 1 bytes
    ------ Row 5
    Pixel 1:   0   0   0
    Pixel 2:   0   0   0
    Pixel 3:   0   0   0
    Pixel 4:   0   0   0
    Pixel 5:   0   0   0
    Padding: 1 bytes
    Done.
    
    BMP-Info:
    Width x Height: 5 x 5
    Depth: 24
    

    Edit: Yes, my image is displaying a red cross. Note that the image is stored upside-down so row 1 of the file is actually row 5 of the image. D'oh forgot to write something to file the code opens, but this is left as an excercise up to you ;).

提交回复
热议问题