はじめまして、美紀です。
C言語で以下のプログラムを作ったんですが
ちゃんと動いてくれません。
内容はビットマップのカラー画像をを白と黒だけに分けるプログラムです。
誰かやさしい人この謎を解明してくれませんか?
いろんな本を見たりして作ったので
自分でもわからないところがたくさんあります。
/*
☆☆☆☆☆☆☆閾値処理プログラム☆☆☆☆☆☆☆
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include Params.h
int bmp_read(unsigned char *image, char *filename);
void threshold(unsigned char image[Y_SIZE][X_SIZE],
unsigned char image2[Y_SIZE][X_SIZE], int thresh, int mode);
int bmp_write(unsigned char *image3, unsigned char image[Y_SIZE][X_SIZE], char *filename);
FILE *fp;
unsigned char image_buf[Y_SIZE][X_SIZE];
void main()
{
unsigned char image[Y_SIZE][X_SIZE];
unsigned char image2[Y_SIZE][X_SIZE];
unsigned char image3[Y_SIZE][X_SIZE];
char *fn;
int sikii = 148, mode = 1, read, write;
printf(始まります\n);
fn = Matu10h.bmp;
read = bmp_read(*image, fn);
threshold(image, image2, sikii, mode);
printf(閾値処理終了\n);
write = bmp_write(*image3, image2, fn);
printf(描写終了\n);
printf(終わります\n);
}
/*---bmp_read---BMP形式のカラー画像をディスクから読み込む------
image: カラー画像配列
xsize: 画像横サイズ
ysize: 画像縦サイズ
filename: ファイル名(.bmp)
-------------------------------------------------------------*/
int bmp_read(unsigned char *image, char *filename)
{
printf(読込中\n);
int i, j;
unsigned char header[54];
fp = fopen(Matu10h.bmp, rb);
if(fp == NULL) {
printf(開かない\n);
return -1;}
else
printf(開けた\n);
fread(header, sizeof(unsigned char), 54, fp);
fread(image_buf, sizeof(unsigned char), (size_t)(long)X_SIZE*Y_SIZE*3, fp);
fclose(fp);
printf(for文開始1\n);
for(i = 0; i < Y_SIZE; i++) {
for(j = 0; j < X_SIZE; j++) {
*(image + X_SIZE*(Y_SIZE-i-1) + j)
= (image_buf[i][j] + 3*(X_SIZE*i + j) + 2);
*(image + X_SIZE*(Y_SIZE-i-1) + j)
= (image_buf[i][j] + 3*(X_SIZE*i + j) + 1);
*(image + X_SIZE*(Y_SIZE-i-1) + j)
= (image_buf[i][j] + 3*(X_SIZE*i + j) );
}
}
printf(for文終了\n);
printf(読込終了\n);
return 0;
}
/*---threshold---閾値処理-----------------
image_in: 入力画像配列
image_out: 出力画像配列
thresh: 閾値
mode: 閾値処理の方法(1,2)
----------------------------------------*/
void threshold(unsigned char image[Y_SIZE][X_SIZE],
unsigned char image2[Y_SIZE][X_SIZE], int thresh, int mode)
{
printf(閾値処理開始\n);
int i,j;
for (i=0; i<Y_SIZE; i++){
for (j=0; j<X_SIZE; j++){
// printf(b=%d ,image_out[i][j]);
switch (mode){
case 2:
if ((unsigned char)image[i][j]<=thresh) image2[i][j]=HIGH;
else image2[i][j]=LOW;
break;
default:
if ((unsigned char)image[i][j]>=thresh) image2[i][j]=HIGH;
else image2[i][j]=LOW;
break;
}
}
}
printf(%d\n, image2[305][480]);
}
/*---bmp_write---カラー画像をディスクにBMP形式で書き出す-------
image: カラー画像配列
xsize: 画像横サイズ
ysize: 画像縦サイズ
filename: ファイル名(.bmp)
-------------------------------------------------------------*/
int bmp_write(unsigned char *image3, unsigned char image2[Y_SIZE][X_SIZE], char *filename)
{
printf(描写中\n);
int i, j;
long file_size, width, height;
unsigned char header[54] = {0x42, 0x4d, 0, 0, 0, 0, 0, 0, 0, 0,
54, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
printf(宣言終了\n);
file_size = X_SIZE * Y_SIZE * 3 + 54;
header[2] = (unsigned char)(file_size & 0x000000ff);
header[3] = (file_size >> 8) & 0x000000ff;
header[4] = (file_size >> 16) & 0x000000ff;
header[5] = (file_size >> 24) & 0x000000ff;
width = X_SIZE;
header[18] = width & 0x000000ff;
header[19] = (width >> 8) & 0x000000ff;
header[20] = (width >> 16) & 0x000000ff;
header[21] = (width >> 24) & 0x000000ff;
height = Y_SIZE;
header[22] = width & 0x000000ff;
header[23] = (height >> 8) & 0x000000ff;
header[24] = (height >> 16) & 0x000000ff;
header[25] = (height >> 24) & 0x000000ff;
printf(ファイルサイズ終了\n);
printf(for文開始2\n);
for(i = 0; i < Y_SIZE; i++){
for(j = 0; j < X_SIZE; j++){
*(image3 + 3*(X_SIZE*i + j) )
= (image2[i][j] + X_SIZE*(Y_SIZE-i-1) + j + (unsigned char)X_SIZE*Y_SIZE*2);
*(image3 + 3*(X_SIZE*i + j) + 1)
= (image2[i][j] + X_SIZE*(Y_SIZE-i-1) + j + (unsigned char)X_SIZE*Y_SIZE );
*(image3 + 3*(X_SIZE*i + j) + 2)
= (image2[i][j] + X_SIZE*(Y_SIZE-i-1) + j );
}
}
printf(for文終了\n);
if ((fp = fopen(syorigo.bmp, wb)) ==NULL) return-1;
fwrite(header, sizeof(unsigned char)X_SIZE*Y_SIZE, 54, fp);
fwrite(image3, sizeof(unsigned char)X_SIZE*Y_SIZE, (size_t)(unsigned char)X_SIZE*Y_SIZE*3, fp);
fclose(fp);
printf(書込み終了\n);
return 0;
}
Params.hの中身です。
#define X_SIZE 480 /*画像の横方向の大きさ*/
#define Y_SIZE 305 /*画像の縦方向の大きさ*/
#define X_EXP 9 /*X_EXP = log2(X_SIZE)*/
#define Y_EXP 9 /*Y_EXP = log2(Y_SIZE)*/
#define HIGH 255 /*2値画像のハイ・レベル*/
#define LOW 0 /*2値画像のロー・レベル*/
よろしくお願いします。本当に困ってます。
> C言語で以下のプログラムを作ったんですが
> ちゃんと動いてくれません。
どのように、うまく動かないんですか?
というか、こんな聞き方では誰もまともな回答は出さないと思いますが。
全く見当違いだったらすみません。まず...
> read = bmp_read(*image, fn);
→ read = bmp_read(image, fn);
> write = bmp_write(*image3, image2, fn);
→ write = bmp_write(image3, image2, fn);
> for(i = 0; i < Y_SIZE; i++) {
> for(j = 0; j < X_SIZE; j++) {
> *(image + X_SIZE*(Y_SIZE-i-1) + j)
> = (image_buf[i][j] + 3*(X_SIZE*i + j) + 2);
> *(image + X_SIZE*(Y_SIZE-i-1) + j)
> = (image_buf[i][j] + 3*(X_SIZE*i + j) + 1);
> *(image + X_SIZE*(Y_SIZE-i-1) + j)
> = (image_buf[i][j] + 3*(X_SIZE*i + j) );
> }
> }
→ 全て代入先が*(image + X_SIZE*(Y_SIZE-i-1) + j)なんで上の2つが意味無いと思うんですが。
冷たいようですが、自分でもよくわかっていないプログラムを
人に解読させるのですか?それでは、あなた自身のためになら
ないのでは無いでしょうか。仮に心優しい人がいて、その人が
わかったとしても、あなたにはわからないと思いますよ。
自分で、こつこつ動きを調べていかないと、自分でプログラムを
作ることなど絶対にできないと思います。まずは自分で頑張って
みてどこが解らないのかをよく考えてみてはいかがでしょうか。
女性の名前で投稿すれば答えて貰えるなんて甘い!
最近そういう人が増えてるってどっかの掲示板に書いてました。
・・・私もそう思う。
んなのわかるわけないじゃん
自分で考えろっつーの!!
皆さんお返事ありがとうございます。
皆さんの言う通りだと思います。
反省してます。
このプログラムでもう2、3ヶ月悩んでいるんです。
プレビュー画面では、真っ黒になってるんですが、
開くと真っ白になってるんです。
何となくなんですけどプログラムも理解はしてます。
いまもがんばっています。誰か助けてくれると
幸いです。
とりあえず、バッファが小さすぎて全部読めていません。
> プレビュー画面では、真っ黒になってるんですが、
> 開くと真っ白になってるんです。
プレビュー画面てなんですか?
てゆーか、デバックってしてます?
「どこまで上手くいって、どこから動作しない」とか問題の切り分けやってます?
「とりあえず作って実行してみたけど上手くいかない」だと解決は無理と思いますけど。
デバックをして実行してます。
実行した後に、元々あるビットマップが
白と黒だけのビットマップになっていれば
いいんですけど、ならないんです。
その元々のビットマップが入ってるフォルダを開いて
その絵をクリックするとプレビューが
小さく出るじゃないですか?
その画面では黒くなってるんです。
でもそのビットマップを開くと、
真っ白になってるんです。
それって、IEでは表示できて、ペイントでは無理ってことですか?
かなり昔のことなんで薄っすらとしか憶えて無いですけど
ビットデータをDWORD単位に合わせないとそういう症状が出たような気がしました。
それとヘッダの部分も怪しい気がします。
↑これに関してはヘッダの定義部分が読みづらいんで読んでません。
それと
BITMAPFILEHEADERと
BITMAPINFOHEADERを使ったほうがわかりやすいです。
プレビューについてはわかりました。
でもデバックの進め方がおかしいような気がします。
プログラムの段階として、
1.ビットマップファイル読みこみ
2.ビットマップ加工
3.ビットマップをファイルに書きこみ
ってやってると思いますが、1と3のみ実施した場合
問題なく同一のビットマップのファイルはできてますか?
問題の切り分けってそういうことです。
プログラム全部出して「これ直して」では見るほうも大変だって事を
知ってください。
はじめまして
いろいろしているみたいですが、まずbmpファイルの形式があっているか調べた方がいいとおもいます。
カラー情報等で、ヘッダがずれていたりしていませんか?
bmpファイルの種類はいろいろあります。
一度そのファイルをの中身を全てバイナリ-エディタ等で確認してみよう。
toruさんの意見も反映しなければなりませんね。
またたくさんのお返事ありがとうございます。
皆さんのお返事本当にうれしいのですが、
自分がなにせ初心者なもので、
皆さんの意見がときどき理解できていません。
とりあえず、皆さんの意見を参考に
bmpを開いて新しい名前で保存するという
プログラムを作ってみましたが、
デバックの途中で強制終了がかかってしまいます。
多分皆さんのおっしゃるとおりバッファの部分が
おかしいのだと自分でも思うのですが、
よくわかりません。厳しい意見でもかまいません
何か返事を書いてくれるとうれしいです。
とりあえず、新しく作ったプログラムのソースコードを
のっけて、その処理のどこで強制終了になるのかを
記載してみるのがよろしいかと思われますが・・・。