dポイントプレゼントキャンペーン実施中!

こんにちは。大学4年のyu-tinと申します。
現在、大学の研究で使用するためのプログラムとして、以下の機能を持ったプログラム作りに取り込んでいます。

1)ビットマップ画像(グレースケール、縦480×横640pixel)を読み込み、
 その画像の1つ1つの画素の輝度値を表示させる
2)読み込んだビットマップ画像を出力させる

しかし、作成したプログラムがうまく行きません。以下の3つの問題が発生しています。

a)0行0列~1行383列までの画素値がおかしい。
 (0,0,0,0,1,1,1,0,2,2,2,0,3,3,3,0,…,254,0,255,255,255,0 となっている)
b)出力した画像の最上部2行程度に、細くて黒い線が表示される。
 (読み込んだ画像と全く同じ画像を出力させたい)
c)出力した画像が、”ディスクエラー”によりPhotoshopで開けない。
 (ペイントでは開ける)

その問題のプログラムは、以下の通りです。
しかし、このプログラムは、他人のプログラムに改良を加えて作成したものです。なので、このプログラム自体、私自身が完璧に理解できていない状況です。

私は、プログラミングに関しては初心者に近いので、丁寧に教えて頂けると大変助かります。
研究が先に進まず、大変困っています…。みなさま、本当に、本当によろしくお願い致します。



//ビットマップ画像に関するプログラム。
//画像の表示と輝度値の表示を行う。

#include<stdio.h>
#include<windows.h>
#include<stdlib.h>

#define X_SIZE 640  //画像の横幅(ピクセル数)
#define Y_SIZE 480  //画像の縦幅(ピクセル数)
#define Z_SIZE 1    //1つの画素に含まれる色の数

void *malloc(size_t size);

void main(void)
{
 int i, j, k;   //ループ用変数 i…縦の画素用, j…横の画素用, k…色数用
 int x=0;    //画像の横幅(ピクセル数)*/
 int y=0;     //画像の縦幅(ピクセル数)
 FILE *fp;

/***********元画像データのメモリ確保*********/
 BYTE ***mae;
 mae=(BYTE ***)malloc(sizeof(BYTE **)*Y_SIZE);
 for(i = 0; i < Y_SIZE; i++){
  mae[i]=(BYTE **)malloc(sizeof(BYTE *)*X_SIZE);
 }
 for(i = 0; i < Y_SIZE; i++){
  for(j = 0; j < X_SIZE; j++){
   mae[i][j]=(BYTE *)malloc(sizeof(BYTE)*Z_SIZE);
  }
 }

/*******画像の読み込み・輝度値の表示*******/
 fp=fopen("sample1.bmp","rb");   //画像”sample1”を開く

 BITMAPFILEHEADER bmfh;
 BITMAPINFOHEADER bmih;

 fread(&bmfh,sizeof(bmfh),1,fp);
 fread(&bmih,sizeof(bmih),1,fp);

 x=bmih.biWidth;  //インフォヘッダに含まれる画像の幅情報をxに代入
 y=bmih.biHeight;  //インフォヘッダに含まれる画像の高さ情報をyに代入

 for(i = 0; i < y ;i++){
  for(j = 0; j < x; j++){
   fread(&mae[i][j][0],sizeof(BYTE),1,fp);
   if(i<640 && j<480)printf("%d, %d, %d\n",i, j, mae[i][j][0]);   //輝度値を表示
  }
 }
 fclose(fp);

/**************画像の表示*************/
 //画像”sample1”を”sample2”という名前で出力する
 fp = fopen("sample2.bmp" ,"wb");

 //ヘッダの書き込み
 fwrite(&bmfh,sizeof(bmfh),1,fp);
 fwrite(&bmih,sizeof(bmih),1,fp);

 for(i = 0; i < bmih.biHeight; i++){
  for(j = 0; j < bmih.biWidth; j++){
   fwrite(&mae[i][j][0],sizeof(BYTE),1,fp);
  }
 }
 fclose(fp);  //ファイルをクローズ

}

A 回答 (2件)

ビットマップファイルにはビット深度が24ビット未満の場合


このファイルで使用されるパレットが登録されています
BITMAPINFOHEADER と 実際のビットイメージの間に
RGBA*何色といったパレットが存在します
グレースケールの8bitなら256個です
何個あるかは BITMAPINFOHEADERのbiClrUsedがそれに当ります
これが0ならbiBitCountをビットシフトして求めます
1 << biBitCountが個数になります
実際のバイトデータとしては
(1 << biBitCount) * sizeof(RGBQ) バイト存在します

したがって
BYTE* pPalette = (BYTE*)calloc( sizeof(RGBQ), (1 << biBitCount) );
とバッファを宣言して

fread(&bmih,sizeof(bmih),1,fp);
の後で
fread( pPalette, sizeof(RGBQ), (1 << biBitCount), fp );
を実行してから
色情報を取得しましょう

書き出すときも同じように
fwrite(&bmih,sizeof(bmih),1,fp);
の後で
fwrite( pPalette, sizeof(RGBQ), (1 << biBitCount), fp );
を実行します

あと動的に確保したバッファは使い終わったら free()で開放しましょう

return 0;の前に
 free( pPalette );
 for(i = 0; i < Y_SIZE; i++){
  for(j = 0; j < X_SIZE; j++){
   free(mae[i][j]);
  }
 }
 for(i = 0; i < Y_SIZE; i++){
  free(mae[i]);
 }
 free(mae);
といった具合に 逆順に開放していきます
    • good
    • 0
この回答へのお礼

返信が大変遅くなってしまいました。申し訳ないです。

redfox63さんのアドバイスを基に改良を加えたところ、
無事にグレースケールのBMP画像を読み込むことができました。

ご意見を頂けて、大変感謝をしております。
ありがとうございました。

まだまだ知識不足ですので、また質問をすることがあると思います。
その際は、よろしくお願い致します。

お礼日時:2007/08/16 16:20

★アドバイス


>しかし、このプログラムは、他人のプログラムに改良を加えて作成したものです。
>なので、このプログラム自体、私自身が完璧に理解できていない状況です。
 ↑
 それなら回答者は誰一人理解できないんでしょうね。多分。
・質問文を読んで思ったのですがグレイスケールのビットマップ画像は 256 色の
 パレット・テーブルは持っているのですか?
 パレット・テーブルはなさそうですよね。
 だから
>c)出力した画像が、”ディスクエラー”によりPhotoshopで開けない。
> (ペイントでは開ける)
 ↑
 となる気がします。
 確かビットマップ画像で 256 色以下は必ずパレット情報を持つ必要があるはずですので
 『Photoshop』ではディスクエラー(BMP形式でないエラー)となるのだと思います。
 ペイントではなぜ開けるのだろ?
 あまり厳しくヘッダをチェックしていないのかも?
・用意したグレースケールのビットマップ画像が正しいと保障できますか?
 きちんとビットマップのヘッダを確認した方が良いですよ。
 縦横ピクセル数、カラー数、その他いろいろ。
・あと次の構造体をちゃんと理解して下さい。
 http://msdn.microsoft.com/library/ja/default.asp …
 パレット・テーブルの RGBQUAD 構造体をちゃんと読み書きすること。
 http://www.alpha-net.ne.jp/users2/uk413/vc/VCT_D …
・以上。
    • good
    • 0
この回答へのお礼

返信が遅くなってしまい、申し訳ありません。


ご意見ありがとうございました。大変参考になりました。

教えて頂いたHPを拝見したところ、私には難しいようでした…。
もう少し勉強をする必要がありそうです。

また疑問が湧いたら、質問をさせて頂きます。
その際はよろしくお願い致します。

お礼日時:2007/08/16 16:29

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!