Erste RGB-Werte für jedes Pixel aus einem 24 bpp Bitmap für die Umwandlung in GBA-Format in C

StackOverflow https://stackoverflow.com/questions/1531268

  •  20-09-2019
  •  | 
  •  

Frage

Ich mag die RGB-Werte für jedes Pixel aus einer .bmp-Datei lesen, so dass ich die bmp in ein Format umwandeln kann geeignet für GBA (gameboy).

Ich brauche nur die RGB für jedes Pixel zu erhalten und diese Informationen dann in eine Datei schreiben.

Ich versuche, die <windows.h> Strukturen zu verwenden:

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

typedef struct
{
    BmpHeader header;
    BmpImageInfo info;
    Rgb colors[256];
    unsigned short image[1];
}BmpFile;

, aber ich nur RGB-Struktur benötigen. Also lassen Sie uns sagen, ich lese „in.bmp“:

FILE *inFile, *outFile;
inFile = fopen("C://in.bmp", "rb");

Rgb Palette[256];
for(i=0;i<256;i++)
{
   fread(&Palette[i],sizeof(Rgb),1,inFile);
}

fclose(inFile);

Ist das richtig? Wie schreibe ich nur die RGB-Informationen in eine Datei?

War es hilfreich?

Lösung

Sie müssen zuerst die Anzahl der Farben in der Embedded-Palette zu bekommen. Dies ist in den DIB-Header.

Dann können Sie alle Farbkomponenten lesen, die die Palette enthalten.

Sie können alle Header-Informationen wie Offset sehen zu wissen, wohin suchen: http: //en.wikipedia. org / wiki / BMP_file_format .

Das sollte funktionieren: (Edit: Add Code schreiben in Datei)

FILE *inFile, *outFile;
BMPHeader header;
BMPImageInfo info;
RGB *palette, *p;
int i = 0;

inFile = fopen("C://in.bmp", "rb");
if( !inFile )
   return;

if( fread(&header, sizeof(BMPHeader), 1, inFile) != 1 )
   return; // Manage error and close file

if( fread&info, sizeof(BMPImageInfo), 1, inFile) != 1 )
   return; // Manage error and close file

if( info.numColors > 0 )
{
   palette = (RGB*)malloc(sizeof(RGB) * info.numColors);
   if( fread(palette, sizeof(RGB), info.numColors, inFile) != info.numColors )
      return; // manage error and close file
}

fclose(inFile)

// Binary method => if read later by another computer
outFile = fopen("path", "wb");
if( !outFile )
   return;

if( fwrite(&info.numColors, sizeof(unsigned int), 1, outFile) != 1 )
   return; // Manage Error and close file

if( fwrite(&palette, sizeof(RGB), info.numColors, outFile) != info.numColors )
   return; // Manage error and close file

fclose(outFile);

// Text method => if read later by human
outFile = fopen("path", "w");
if( !outFile )
   return;

for( i=0; i<info.numColors; ++i )
{
   p = &palette[i];
   if( fprintf(outFile, "R:%d, G:%d, B:%d\n", p->red, p->green, p->blue) < 0 )
      return; // Manage error and close file
}

fclose(outFile);

Andere Tipps

Wenn Sie auf Fenster können Sie mit der Loadbitmap Funktion von win32

dann angesichts der Griff wandelt es in ein DIB-Bitmap und erhalten auf die Pixel auf diese Weise

habe ich ein wenig getestet und erweitert Patrice Programm ein bisschen. Ich bin kein guter C-Programmierer, so dass alle Kredite gehen zu ihm und meine Teile sind nicht so elegant wie seine -. Leid, dass

. Achtung: große Quellcode vor

#include <stdio.h>
#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; j<info.height; j++ ) {
        printf( "------ Row %d\n", j+1 );
        read = 0;
        for( i=0; i<info.width; i++ ) {
            if( fread(pixel, 1, sizeof(Rgb), inFile) != sizeof(Rgb) ) {
                printf( "Error reading pixel!\n" );
                return -1;
            }
            read += sizeof(Rgb);
            printf( "Pixel %d: %3d %3d %3d\n", i+1, pixel->red, 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;

}

Dieses Programm liest die Pixelinformation in der Datei gespeichert. Es nimmt die Polsterung Rechnung funktioniert aber nur mit bmps mit 24 Bit pro Pixel Farbtiefe (Wenn Sie andere Tiefen benötigen, werden Sie die Rgb Struktur anpassen müssen). Hoffe, das hilft Ihnen, aber wie gesagt, es ist nur eine Erweiterung von Patrice Code.

Hier ist ein Beispiel für die Ausgabe von meiner Testdatei:

$ ./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: Ja, mein Bild wird ein rotes Kreuz angezeigt wird. Man beachte, dass das Bild gespeichert ist, Kopf nach unten, so 1 der Datei tatsächlich Zeile 5 der Bildzeile ist. D'oh vergessen, etwas zu schreiben der Code öffnet eine Datei, aber dies wird als excercise links bis zu Ihnen;)

.

Wenn Sie garantiert sind, dass es ein unkomprimiertes 24bpp Bitmap und seine Breite ist durch 4 teilbar, ist es relativ einfach:

  1. Lesen Sie eine BmpHeader am Anfang der Datei.
  2. Ohne suchen, lesen Sie ein BmpImageInfo.
  3. Positioniert auf die BmpHeader der offset Bytes von den Anfang der Datei . Beachten Sie, dass es keine Palette ist (zumindest nicht, was wir kümmern uns um) in 24-Bit-Bitmaps!
  4. Read BGR-Triplets (in dieser Reihenfolge, und es gibt kein reserved ungenutzt Mitglied hier). Es wird (BmpImageInfo-Mitglieder) width * abs(height) Drillinge sein. Soweit ich mich erinnere, wenn height positiv ist (der Standardfall), die erste Zeile der Farbe lesen Sie die unten Zeile des Bildes sein, von dort hinauf. Wenn height negativ ist, ist jedoch die erste Zeile der Farbe in der Datei der oben des Bildes, ablaufend von dort.

Wenn Sie nicht diese Garantien machen, dann werden die Dinge viel komplizierter.

Disclaimer: Ich bin tooting grundlos mein eigenes Horn hier Vor Jahren schrieb ich ein winziges (eine Quelldatei) Dienstprogramm genau das zu tun, was du redest, in einem tragbaren (100%. ANSI C) Art und Weise: glbmp libbmpread . Seine Quelle könnte etwas Licht auf das Problem werfen -. Es Griffe uncompresed (kein RLE) Bitmaps jeder Bit-Tiefe, und sollte gut auf einem GBA laufen

Siehe Wikipedia-Seite von BMP-Datei-Format, das viele Informationen über die Struktur der Datei bereitstellt und sollten Sie es analysieren helfen.

http://en.wikipedia.org/wiki/BMP_file_format

In Ihrem Code Sie zunächst die Startadresse der Daten lesen (in Datei-Header angegeben) und die Höhe des Bildes. Dann sucht auf diese Position. Danach können Sie für Pixel in einer Zeile Pixel gelesen (die Header gibt an, wie viele Bits pro Pixel) und Pflege der am Ende des es Polsterung 32-Bit zu nehmen. Man beachte, dass in einem 24-Bit-Bild (RGB) die Informationen in BGR Reihenfolge gespeichert werden. Auch wenn der Höhenwert nicht negativ ist, wird das Bild auf dem Kopf gespeichert.

Ich bin mit dem BMP-Dateiformat nicht vertraut, aber nicht müssen Sie zuerst in den Header-Informationen lesen? So etwas wie:

BmpHeader header;
fread(&header,sizeof(BmpHeader),1,inFile);

und lesen Sie in der detaillierten Bildinformationen, die Sie benötigen:

BmpImageInfo info;
fread(&info,sizeof(BmpImageInfo),1,inFile);

und auch in Paletteninformationen lesen.

Sobald Sie, dass Sie die Dateigröße wissen und Daten gegenüber. Sie können genügend Platz vorbelegt und in auf einmal lesen, was einfachste sein kann. Alternativ können Sie in in Stücke und Parse zu lesen, wie du gehst (reduziert Chance, nicht genug Speicher, aber das Parsen komplizierter ist).

Sie werden auch von der Info-Bereich, ob die Komprimierung aktiviert ist, Bildabmessungen etc.

Wenn Sie liest in alle auf einmal, Sprung zum Offset der Daten, und so etwas wie:

Rgb* rgb = offset;
blueVal = rgb->blue;
greenVal = rgb->green;
redVal = rgb->red;
rgb += sizeof( Rgb );

und so weiter. Offensichtlich wird dieser Code überprüft nicht für Fehler, Ende des Puffers, und so weiter, so dass Sie müssen das tun. Sie werden wahrscheinlich auch in Paletteninformationen lesen Sinn der Bilddaten zu machen.

Oder, wie jemand anderes sagte, Blick auf die Format-Spezifikation auf Wikipedia

Wenn die BMP-Datei hat eine Palette dann die folgenden Code sollte Arbeit:

  FILE *inFile, *outFile;
  inFile = fopen("C:/in.bmp", "rb");
  Rgb Palette[256];
  if ( inFile ) {
    // Bypass headers
    fseek(inFile, sizeof(BmpHeader) + sizeof(BmpImageInfo), SEEK_SET);
    // Load the whole palette
    fread(Palette, sizeof(Palette), 1, inFile);
    fclose(inFile);
  }

Sie finden es möglicherweise nützlich bei einigen C-Code sehe ich vor vielen Jahren für das Lesen und Schreiben von BMP-Dateien, befindet sich in schrieb:

http://david.tribble.com/src/bmp/bmp.html

Ich glaube, es behandelt die verschiedenen Pixel-Bit-Größen (1/2/4/8/24) sowie RLE-Komprimierung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top