C言語による画像処理 画像サイズ変更

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Mr.beginner
記事: 2
登録日時: 10年前
住所: 埼玉県

C言語による画像処理 画像サイズ変更

#1

投稿記事 by Mr.beginner » 10年前

C言語で,画像処理の勉強を行っています.画像サイズを変更するプログラムを作成しましたが,出力画像が添付した画像のように,X_SIZEが1/4になったのですが,残りの部分が黒くなってしまいました.
定義箇所をunsigned char screen[Y_SIZE][X_SIZE][3],compress[Y_SIZE][X_SIZE/4][3];,書き込みをfwrite(compress,1,(X_SIZE/4)*Y_SIZE*3,fp);としてみたのですが,保存されませんでした・・・

この黒色の部分を消したいのですが,どなたかご教授お願いします.

以下に,作成したプログラムを載せておきます.

コード:

#include <stdio.h>
#include <stdlib.h>
#define X_SIZE 1916/*画像の横サイズを定義*/
#define Y_SIZE 181/*画像の縦サイズを定義*/

unsigned char screen[Y_SIZE][X_SIZE][3],compress[Y_SIZE][X_SIZE][3];

int main() 
{
 FILE *fp;
 unsigned char header[54];
 char input_file[100],henkan_file[100];

 /*画像ファイル読み込み*/
 printf("処理を行う画像ファイル名:.(拡張子:bmp)\n---");
 scanf("%s",input_file);
 printf("処理を行う画像ファイル:「 %s 」.\n\n",input_file);
 fp=fopen(input_file,"rb"); 
 if((fp=fopen(input_file,"rb"))==NULL){
 printf("画像ファイルが正常に開けませんでした.\n");
 exit(1);
 }
 fread(header,1,54,fp);
 fread(screen,1,X_SIZE*Y_SIZE*3,fp);
 fclose(fp);

 /*サイズ変更*/
 int x,y,i;
 for(i=0;i<3;i++){
  for(y=0;y<Y_SIZE;y++){
   for(x=0;x<X_SIZE/4;x++){
    compress[y][x][i]= (screen[y][x*4+0][i] +screen[y][x*4+1][i] +screen[y][x*4+2][i] +screen[y][x*4+3][i]) /4;
   }
  }
 }
 /*画像ファイル保存*/
 printf("保存する画像ファイル名:.(拡張子:bmp)\n---");
 scanf("%s",henkan_file);
 fp=fopen(henkan_file,"wb");
 if((fp=fopen(henkan_file,"wb"))==NULL){
 printf("画像ファイルが正常に開けませんでした.\n");
 exit(1);
 } 
 fwrite(header,1,54,fp);
 fwrite(compress,1,X_SIZE*Y_SIZE*3,fp);
 fclose(fp);
 printf("画像ファイル「 %s 」を保存しました.\n",henkan_file);
 printf("全ての作業が終了しました.\n");
 
 return 0;
}
添付ファイル
new_ggg.jpg
new_ggg.jpg (34.31 KiB) 閲覧数: 9335 回

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: C言語による画像処理 画像サイズ変更

#2

投稿記事 by softya(ソフト屋) » 10年前

X_SIZEが1/4になるのなら
compress[Y_SIZE][X_SIZE/4][3];
では無いでしょうか?
となると出力も
fwrite(compress,1,X_SIZE/4*Y_SIZE*3,fp);
なのでは?

あとインデントも綺麗に揃えて頂くと読みやすくなります。

コード:

#include <stdio.h>
#include <stdlib.h>
#define X_SIZE 1916/*画像の横サイズを定義*/
#define Y_SIZE 181/*画像の縦サイズを定義*/

unsigned char screen[Y_SIZE][X_SIZE][3], compress[Y_SIZE][X_SIZE][3];

int main() {
	FILE *fp;
	unsigned char header[54];
	char input_file[100], henkan_file[100];

	/*画像ファイル読み込み*/
	printf( "処理を行う画像ファイル名:.(拡張子:bmp)\n---" );
	scanf( "%s", input_file );
	printf( "処理を行う画像ファイル:「 %s 」.\n\n", input_file );
	fp = fopen( input_file, "rb" );
	if( ( fp = fopen( input_file, "rb" ) ) == NULL ) {
		printf( "画像ファイルが正常に開けませんでした.\n" );
		exit( 1 );
	}
	fread( header, 1, 54, fp );
	fread( screen, 1, X_SIZE * Y_SIZE * 3, fp );
	fclose( fp );

	/*サイズ変更*/
	int x, y, i;
	for( i = 0; i < 3; i++ ) {
		for( y = 0; y < Y_SIZE; y++ ) {
			for( x = 0; x < X_SIZE / 4; x++ ) {
				compress[y][x][i] = ( screen[y][x * 4 + 0][i] + screen[y][x * 4 + 1][i] + screen[y][x * 4 + 2][i] + screen[y][x * 4 + 3][i] ) / 4;
			}
		}
	}
	/*画像ファイル保存*/
	printf( "保存する画像ファイル名:.(拡張子:bmp)\n---" );
	scanf( "%s", henkan_file );
	fp = fopen( henkan_file, "wb" );
	if( ( fp = fopen( henkan_file, "wb" ) ) == NULL ) {
		printf( "画像ファイルが正常に開けませんでした.\n" );
		exit( 1 );
	}
	fwrite( header, 1, 54, fp );
	fwrite( compress, 1, X_SIZE * Y_SIZE * 3, fp );
	fclose( fp );
	printf( "画像ファイル「 %s 」を保存しました.\n", henkan_file );
	printf( "全ての作業が終了しました.\n" );

	return 0;
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: C言語による画像処理 画像サイズ変更

#3

投稿記事 by softya(ソフト屋) » 10年前

あと忘れてました。headerのX_SIZEも1/4にする必要があります。
headerが構造体宣言されていないので、ちょっと面倒ですね。

headerは次のような構造をしています。
「bmp ファイルフォーマット」
http://www.kk.iij4u.or.jp/~kondo/bmp/
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Mr.beginner
記事: 2
登録日時: 10年前
住所: 埼玉県

Re: C言語による画像処理 画像サイズ変更

#4

投稿記事 by Mr.beginner » 10年前

ご指摘いただいた箇所を修正し,実行したのですが,出力画像が添付した画像になりました...

コード:

#include <stdio.h>
#include <stdlib.h>
#define X_SIZE 1916/*画像の横サイズを定義*/
#define Y_SIZE 181/*画像の縦サイズを定義*/
 
unsigned char screen[Y_SIZE][X_SIZE][3], compress[Y_SIZE][X_SIZE/4][3];
 
int main() {
    FILE *fp;
    unsigned char header[54];
    char input_file[100], henkan_file[100];
 
    /*画像ファイル読み込み*/
    printf( "処理を行う画像ファイル名:.(拡張子:bmp)\n---" );
    scanf( "%s", input_file );
    printf( "処理を行う画像ファイル:「 %s 」.\n\n", input_file );
    fp = fopen( input_file, "rb" );
    if( ( fp = fopen( input_file, "rb" ) ) == NULL ) {
        printf( "画像ファイルが正常に開けませんでした.\n" );
        exit( 1 );
    }
    fread( header, 1, 54, fp );
    fread( screen, 1, X_SIZE/4 * Y_SIZE * 3, fp );
    fclose( fp );
 
    /*サイズ変更*/
    int x, y, i;
    for( i = 0; i < 3; i++ ) {
        for( y = 0; y < Y_SIZE; y++ ) {
            for( x = 0; x < X_SIZE / 4; x++ ) {
                compress[y][x][i] = ( screen[y][x * 4 + 0][i] + screen[y][x * 4 + 1][i] + screen[y][x * 4 + 2][i] + screen[y][x * 4 + 3][i] ) / 4;
            }
        }
	 }

    /*画像ファイル保存*/
    printf( "保存する画像ファイル名:.(拡張子:bmp)\n---" );
    scanf( "%s", henkan_file );
    fp = fopen( henkan_file, "wb" );
    if( ( fp = fopen( henkan_file, "wb" ) ) == NULL ) {
        printf( "画像ファイルが正常に開けませんでした.\n" );
        exit( 1 );
    }
    fwrite( header, 1, 54, fp );
    fwrite( compress, 1, X_SIZE/4 * Y_SIZE * 3, fp );
    fclose( fp );
    printf( "画像ファイル「 %s 」を保存しました.\n", henkan_file );
    printf( "全ての作業が終了しました.\n" );
 
    return 0;
}
添付ファイル
new_cc2.jpg
new_cc2.jpg (16.85 KiB) 閲覧数: 9270 回

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: C言語による画像処理 画像サイズ変更

#5

投稿記事 by softya(ソフト屋) » 10年前

headerのxサイズ情報を修正されていないので、これが原因かもしれません。

【補足】上の方に参考サイトを書いてありますので見て下さいね。BITMAPINFOHEADERの所にあるbiWidthです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: C言語による画像処理 画像サイズ変更

#6

投稿記事 by ISLe » 10年前

bmpはピクセルデータの水平サイズを4の倍数にそろえる必要があります。
変換後のサイズは詰め物が必要なので、3次元配列を使ったこのコードでは対応できないのではないかと。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: C言語による画像処理 画像サイズ変更

#7

投稿記事 by softya(ソフト屋) » 10年前

ISLe さんが書きました:bmpはピクセルデータの水平サイズを4の倍数にそろえる必要があります。
変換後のサイズは詰め物が必要なので、3次元配列を使ったこのコードでは対応できないのではないかと。
しまった。それを忘れていました。
それにサイズ固定なデータ限定なので可変長に対応 = 動的確保が必要になりそうですね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: C言語による画像処理 画像サイズ変更

#8

投稿記事 by ISLe » 10年前

水平方向はRGB要素を展開したサイズで2次元配列にすれば、特に動的確保は必須とはならないかと。
添字の計算にひと手間加える必要がありますが。

アバター
usao
記事: 1887
登録日時: 11年前

Re: C言語による画像処理 画像サイズ変更

#9

投稿記事 by usao » 10年前

No4のline23:
>fread( screen, 1, X_SIZE/4 * Y_SIZE * 3, fp );

読むときはちゃんと全部読まないといかんのではないだろうか.
→ここではX_SIZE/4の/4は不要.
(あと,
 >bmpはピクセルデータの水平サイズを4の倍数にそろえる必要があります。
 これがあるので,画素データ部のサイズ計算は一般には(X_SIZE * Y_SIZE * 3)ではダメかと.
 今はたまたま #define X_SIZE 1916 なる4の倍数な横幅の画像を読んでいるためにこれでも読めるだろうけど.)

閉鎖

“C言語何でも質問掲示板” へ戻る