

こんにちは。大学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); //ファイルをクローズ
}
No.1ベストアンサー
- 回答日時:
ビットマップファイルにはビット深度が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);
といった具合に 逆順に開放していきます
返信が大変遅くなってしまいました。申し訳ないです。
redfox63さんのアドバイスを基に改良を加えたところ、
無事にグレースケールのBMP画像を読み込むことができました。
ご意見を頂けて、大変感謝をしております。
ありがとうございました。
まだまだ知識不足ですので、また質問をすることがあると思います。
その際は、よろしくお願い致します。
No.2
- 回答日時:
★アドバイス
>しかし、このプログラムは、他人のプログラムに改良を加えて作成したものです。
>なので、このプログラム自体、私自身が完璧に理解できていない状況です。
↑
それなら回答者は誰一人理解できないんでしょうね。多分。
・質問文を読んで思ったのですがグレイスケールのビットマップ画像は 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 …
・以上。
返信が遅くなってしまい、申し訳ありません。
ご意見ありがとうございました。大変参考になりました。
教えて頂いたHPを拝見したところ、私には難しいようでした…。
もう少し勉強をする必要がありそうです。
また疑問が湧いたら、質問をさせて頂きます。
その際はよろしくお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ファイルアップロードのダイア...
-
SendMailがエラーを返さない
-
CSV出力にHTMLが入ってしまう
-
.phpファイルが、表示されない
-
PHPからメールを送る@さくらイ...
-
centos6のlogにscript not foun...
-
ob_end_clean と ob_clean の違...
-
php.ini を設定を変更すると再...
-
CFileDialogの最初のディレクト...
-
IIS+PHP スクリプトから仮想デ...
-
glide3x.dllがないと表示されま...
-
PHPのif文でその処理を途中で抜...
-
PHP PDOライブラリが読み込まれ...
-
include先でのinclude元の変数...
-
try~catch構文は、どういうメ...
-
FTPコマンドでディレクトリごと...
-
Notice: Undefined offset: 1を...
-
PHPでメールを受信するには?
-
テキストボックスにデータベー...
-
fopenでファイルが開かない場合...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBSの「MsgBox」について
-
拡張子php画像をjpg画像等に変...
-
PHPで吐き出した画像にリンクを...
-
Illustratorで文字と画像を流し...
-
SQLiteに画像を格納したい
-
iphoneで虫眼鏡の作り方
-
Borland C++ Builder
-
<ASP.NET+C#+MSDE> JPEG画像の...
-
PHPでPDFを画像で表示したい
-
フォルダの属性について
-
PythonのTkinter詳しい方へ。画...
-
PHPで画像アップロード時にサイ...
-
透過PNGが透過されない!!
-
libpng 24bpp rawをPNGに変換す...
-
VBAでJPGサイズ変更
-
PHPでGmail署名ジェネレータ
-
PHPで画像サイズの変更
-
画像のアップロードができない
-
画像の張りかたについて
-
C# Excelファイルへの画像挿入。
おすすめ情報