っRGB値を各ピクセルから24bppビットマップ変換をGBAフォーマットC

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

  •  20-09-2019
  •  | 
  •  

質問

私は読みたいのRGB値を各ピクセルから .bmp ファイルだったので、変換の bmp フォーマットのレポートに適したGBA(ゲームボーイアドバンスです。

りさんのRGB各ピクセルとして書きこれらの情報をファイルです。

私を利用しようと <windows.h> 構造

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;

っRGB struct.いということかを読んだ"。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);

すが、いかがでしょうか?どうかだけを書けばいいのでRGB情報をファイルとは何ですか?

役に立ちましたか?

解決

あなたは、埋め込まれたパレットの色の数が利用可能に取得する最初の必要があります。これは、DIBヘッダーで提供されます。

そして、あなたはパレットを含むすべての色成分を読み取ることができます。

にhttp://en.wikipediaを求めるwhereto知ってオフセットのように

あなたはすべてのヘッダー情報を見ることができます。 ORG /ウィキ/ BMP_file_formatするます。

この作業をする必要があります:(編集:ファイルに書き込むようにコードを追加します)。

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

他のヒント

は、Windows上にある場合は、 win32の

からLoadBitmap の機能

その後、DIBビットマップに変換処理し、各画素にその方法を取得与えられた。

私は、テストのビットを行なったし、パトリスのプログラムビットを拡張しました。私はすべてのクレジットは彼に行くと、私の部分は、彼のようにエレガントではない、優れたCプログラマではないんだ - 。そのため申し訳ありません。

警告:先に巨大なソースコード

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

}

このプログラムは、ファイルに格納されたピクセル情報を読み出します。それは(あなたが他の深さが必要な場合は、あなたがRGB構造体をカスタマイズする必要があります)考慮にパディングを取るだけのピクセルの色深度ごとに24ビットのBMPはで動作します。これはあなたが役立ちますが、私が言ったように、それはパトリスのコードの拡張子だけ願っています。

ここに私のテストファイルの出力例を示します。

$ ./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

編集:はい、私のイメージは、赤い十字が表示されています。画像が逆さまに記憶されているので、ファイルの1が実際に画像の5行である行。 )

;ああD'コードが開くファイルに何かを書くのを忘れて、これはあなたに運動し、最大として残されています。

だが保証されることでされた、圧縮解除された24bppビットマップ幅が4で割り切れるので、比較的シンプルです:

  1. を読む BmpHeader 開始時のファイルです。
  2. なめを読む BmpImageInfo.
  3. を求める BmpHeader's offset バイトから のファイルの先頭.場合がありますので注意してないパレット(少なくとも、つき24ビットのビットマップ!
  4. 読みBGR励をこの順序はありません reserved 未利用会員ます。があります(BmpImageInfo'sメンバー) width * abs(height) 励.かったと記憶している場合 height が正の標準の場合、最初の行の色をだすの 線画像の上からである。の場合 height が負のが最初の行の色のファイルは、 トップ 画像のもあります。

できない場合はその保証、そしても良い取引が複雑化してきております。

免責事項:私は無償tooting自分のホーン。 年前に書いた小さな(一ソースファイル)ユーティリティというだけの話、ポータブル(100%ANSI C)方法: glbmp libbmpread.その源泉かを明らかにする--取り扱いuncompresed(RLE)ビットマップの任意のビット深度、実行中アプリコット、GBA.

ファイルの構造に関する情報の多くを提供し、あなたはそれを解析するために役立つはずの.bmpファイルフォーマットのWikipediaのページを参照してください。

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

あなたのコードでは、最初の(ファイルヘッダに指定された)データの開始アドレスと画像の高さを読み取ることがあります。そして、この位置へのシーク。そのあと、ピクセルによって1つの行の画素で読み出し(ヘッダはピクセルあたりビット数を指定する)と、それの終わりに、32ビットのパディングの世話をしなければなりません。 24ビットの画像(RGB)の情報は、BGRの順に格納されていることに留意されたいです。高さの値が負でない場合にも、画像が上下逆に格納されます。

私は、BMPファイル形式に慣れていないんだけど、あなたは最初のヘッダ情報を読み込む必要はないでしょうか?ような何かます:

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

とあなたが必要とされ、詳細な画像情報を読み込みます:

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

と同様にパレット情報を読み込むます。

あなたがオフセットファイルサイズとデータを知っているだろうことをしたら。あなたは十分なスペースを事前に割り当てる最も簡単なことかもしれない、すべてを一度に読み込むことができます。また、あなたが塊で読み込むと、あなたが行っているように解析できた(十分なメモリを持っていない可能性を低減するが、解析が複雑である)。

圧縮は画像の大きさなど、有効になっている場合ます。

また、情報セクションから知っていますよ あなたが一度にすべてに読んでいる場合は、

は、データのオフセットにジャンプ、など、何かの操作を行います。

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

のように。明らかに、そのコードは、エラーのためにバッファの終わりをチェックしていない、というように、あなたがそれを行う必要があります。おそらく、また、画像データの意味を理解するために、パレット情報を読み込む必要があります。

あるいは、他の誰かが言ったように、Wikipediaのフォーマットの仕様を見てみます。

BMPファイルは、その後、以下のコードをパレットを持っている場合は、のはずの仕事ます:

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

あなたはそれが便利な私はに位置BMPファイルを、読み書きのために何年も前に書いたいくつかのCコードを見るかもしれません。

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

私はそれが様々な画素ビットサイズ(1/2/4/8/24)ならびにRLE圧縮を処理すると信じている。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top