• ベストアンサー

c言語による画像処理について

いつもお世話になってます。 c言語を使った画像処理を学び始めました。 入力画像の白(RGB値255,255,255)以外の画像を黒(RGB値0,0,0) に変換するプログラムを作成したいと思っているのですが、 入力画像の大きさによっては正常に命令を実行してくれないことがあるので、 改善点をご教示いただきたいと考え投稿させていただきました。ソースプログラムは #include<stdio.h> #define nx 100 //画像の幅 #define ny 100 //画像の高さ int main(void) { FILE *fp,*fp2; int i,j; unsigned char header[54]; unsigned char screen[nx][ny][3]; /* ファイルから読む */ fp=fopen("input.bmp","rb"); //ビットマップ形式 ,24ビットカラー fread(header,1,54,fp); // ヘッダ(54バイト)を飛ばす */ fread(screen,1,nx*ny*3,fp); // 残りはデータ(最下行から順に入る) //(255,255,255)以外なら黒(0,0,0)に for(j=0;j<ny;j++) for(i=0;i<nx;i++) if(screen[j][i][0]!=255||screen[j][i][1]!=255||screen[j][i][2]!=255){ screen[j][i][0]=0; screen[j][i][1]=0; screen[j][i][2]=0; } fclose(fp); /* ファイルに書く */ fp=fopen("output.bmp","wb"); fwrite(header,1,54,fp); /* ヘッダ */ fwrite(screen,1,nx*ny*3,fp); /* データ */ fclose(fp); return 0; } となっています。ここで、画像の高さ、幅を100以下にすると正常に変換できなくなります。 どなたか原因がお分かりでしたらお知らせ願えないでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.4

#3 訂正 自分的に256BMPメインで扱ってたんで一応確認してみましたが 24ビットだとちょっと変わった変化してます 24ビットカラーのとき横4で割り切れないピクセル数だと データとしては 1Pixl×3バイト(BGR) + 余りバイト数 となっているようです ここら辺は御自分でペイント使って出来たファイルの 中身調べれば分かると思います 上のような動作ですと#3で書いたコードでは結局動かないはずです コードを全面的に書き直します(Windows前提のVCコード) ついでにサイズはファイルからそのまま読んでます エラー処理などは省いています #include <stdio.h> #include <stdlib.h> #include <windows.h> int main() { FILE *fp; BITMAPFILEHEADER fileheader; BITMAPINFOHEADER header; RGBTRIPLE *rgb; unsigned char *screen; int size; /* ファイルから読む */ fp=fopen("c:\\aaa.bmp","rb"); //ビットマップ形式 ,24ビットカラー fread(&fileheader,sizeof(fileheader), 1,fp); // ヘッダ(54バイト)を飛ばす */ fread(&header,sizeof(header), 1,fp); // ヘッダ(54バイト)を飛ばす */ // size = ((header.biWidth % 4) == 0) ? (header.biWidth * header.biHeight * 3) : (header.biWidth * header.biHeight * 3) + header.biWidth % 4; size = fileheader.bfSize - (sizeof(fileheader) + sizeof(header)); screen = (unsigned char *)malloc(size); fread(screen,size,1,fp); // ヘッダ(54バイト)を飛ばす */ fclose(fp); rgb = (RGBTRIPLE *)screen; //(255,255,255)以外なら黒(0,0,0)に for(int y = 0 ; y < header.biHeight ; y ++) { for(int x = 0 ; x < header.biWidth ; x ++, rgb ++) { if((rgb->rgbtRed != 255) || (rgb->rgbtGreen != 255) || (rgb->rgbtBlue != 255)) { rgb->rgbtRed = 0; rgb->rgbtGreen = 0; rgb->rgbtBlue = 0; } } char *addr = ((char *)rgb) + (header.biWidth % 4); rgb = (RGBTRIPLE *)addr; } free(screen); //別ファイルに書く分は手抜き }

その他の回答 (6)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.7

#6です。 >>添字の順番が逆になっています >とのことですが、どうやら画像のデータは(y,x)という風に書かれている>ようなので、 >これで正しいと思っています。 もう一度よくみてください screenの宣言は > unsigned char screen[nx][ny][3]; で、添字の範囲は[0~(nx-1)][0~(ny-1)][0~2]となっています。 対して > for(j=0;j<ny;j++) > for(i=0;i<nx;i++) > if(screen[j][i][0]!=255||screen[j][i][1]!=255||screen[j][i][2]!=255){ では[j=0~(ny-1)]i=[0~(nx-1)][0~2]を使おうとしています。 最初のプログラムではnx=100,ny=100なので入れ替わっても同じでしたが、これを nx=200,ny=100 としたら [0~(200-1)][0~(100-1)][0~2]と宣言して [0~(100-1)][0~(200-1)][0~2]とで使おうとすることになります。 Cでは添字の範囲外のチェックを行いません。「添字が範囲外」というエラーは出ません。その添字で指定された領域をアクセスしようとします。 結果、たまたまそこにあった関係ない変数が書き変わったり、そもそもアクセス制限にかかって致命的はエラーとなったりします。 今回は最終的に動的確保で落ちつきそうなので、直接関係ないところではありますが、指摘されていただきました。

branchmen
質問者

お礼

お返事ありがとうございます。 ご指摘いただいた内容をよく理解せず返答してしまいました。申し訳ございません。 確かに変数宣言時に unsigned char screen[nx][ny][3]; となっていますね。 これでは添え字が間違っていると認めざるを得ません。 再度ご指摘いただかなければ誤った認識のままでいるところでした。 ご指摘、本当にありがとうございます

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.6

100x100のときも結果としてうまく読めてるみたいですが > unsigned char screen[nx][ny][3]; と宣言しておいて > for(j=0;j<ny;j++) > for(i=0;i<nx;i++) > if(screen[j][i][0]!=255||screen[j][i][1]!=255||screen[j][i][2]!=255){ と添字の順番が逆になっています。

branchmen
質問者

お礼

なるほど、そうなっていたのですね! おかげさまで無事問題が解決しました。 たびたび質問に答えてくださり、本当にありがとうございます。

branchmen
質問者

補足

失礼しました。 御礼を送る相手を間違えてしまいました。 ご回答ありがとうございます。 >添字の順番が逆になっています とのことですが、どうやら画像のデータは(y,x)という風に書かれているようなので、 これで正しいと思っています。 この認識は間違いなのでしょうか?

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.5

#4補足 #4に書いてあるコメントは元々のソースのコピーで残っててめちゃくちゃです (直し忘れたのをそのまま乗せてしまいました環境はVC6++のコンソールアプリ) 一応データサイズ自分で求めましたがめんどくさいので結局 ファイル情報に記載してあるサイズ分を読むようにしています (計算方法としてコメント行で記載してあるだけだと思ってください) >char *addr = ((char *)rgb) + (header.biWidth % 4); >rgb = (RGBTRIPLE *)addr; ここでデータポインタを次の行の位置に合わせています 本来はエラー処理含めファイルの中身がBMPなのか 24ビットカラーなのか等もチェックする方がより正確なものになります

branchmen
質問者

お礼

なるほど、そうなっていたのですね! おかげさまで無事問題が解決しました。 たびたび質問に答えてくださり、本当にありがとうございます。

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.3

>自分のプログラムにどう組み込めばいいのか、ご教示願えませんでしょうか? とっても安直な方法です >#define nx 100 //画像の幅 #define nx_org 100 //画像の幅 int nx; int main(void) { nx = (nx_org % 4) 0 ? nx_org : (nx_org / 4 + 1) * 4; >unsigned char screen[nx][ny][3]; コンパイラ次第でエラーになったりならなかったりするので エラーの場合 unsigned char *screen; screen = memalloc(sizeof(unsigned char), nx * ny * 3); などと変えてください アロケーションした場合 free もお忘れなく それ以外もともとの御自分のコードで動くはずです (保管部分のデータに対しては一切操作してません) コンパイル・確認して無くてここに直に書いたんで間違ってるかも (イメージだけつたわりゃ良いかなと)

branchmen
質問者

お礼

そのようにすればよかったのですか。 さっそくご教示いただいた部分をプログラムに取り込むと >unsigned char screen[nx][ny][3]; の部分でエラー「定数式が必要です」 のエラーがでてしまいます。 unsigned char *screen; screen = memalloc(sizeof(unsigned char), nx * ny * 3); としてみましたが、こちらのプログラムの >//(255,255,255)以外なら黒(0,0,0)に 以下がエラー(配列または、ポインタでない変数に添字が使われました) となり、コンパイルできませんでした。 ポインタは扱ったことがないのでどのように変更すればいいのか分かりません。 恐縮ですが、この部分の対処法をご教示願えないでしょうか?

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.2

ビットマップは1ライン4バイト境界で作成しないといけませんが その辺りの問題ではないですか? それ以外はプログラム的に間違ってないと思います 4バイト境界になってないBMPを作るためには不足分のバイトを自分で 補ってファイルを作る必要があります (その部分のデータは何でも良かったと思いますが0にしておいた方がいいとは思います) 例) 横 2pixl のBMP作りたいときは 横 4pixlのデータを作る (2pxl分のデータは0にしておく) ということです BMP構造としては以下参照 http://www.kk.iij4u.or.jp/~kondo/bmp/

branchmen
質問者

お礼

ご回答いただきありがとうございます。 おかげさまでbmpの内容について少し理解できました。対処する方針もわかりました。 しかしながら、実際に直接画像データを操作するとなると、勝手がわからず >>4バイト境界になってないBMPを作るためには不足分のバイトを自分で 補ってファイルを作る必要があります とのことですが、具体的にはどのように操作すればよいのでしょうか? お示しいただいたサイトのプログラム line = (Width * BitCount) / 8; // 1 ラインあたりのデータ数 if ((line % 4) != 0) { line = ((line / 4) + 1) * 4; // 4byte 境界にあわせる } for(i = 0; i < Height; i++) { position = OffBits + line * (Height - (i + 1)); // 行の先頭位置 fseek(fp, position, SEEK_SET); fread(buf, line, 1, fp); // 値の読み込み } を自分のプログラムにどう組み込めばいいのか、ご教示願えませんでしょうか?

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

あなたのいう「正常に変換できない」がどのようなことをさしているのかさっぱりわかりませんが, 画像の大きさを画像自身からとるようにすればいいのでは?

branchmen
質問者

補足

ご回答ありがとうございます。 >>「正常に変換できない」がどのようなことをさしているのかさっぱりわかりません とのことですので、内容をお伝えします。 具体的には黒色への変換が途中で終わってにしまいます。 赤い四角形だけ描いてある画像に対しこのプログラムを実行すると 四角の下半分だけ黒くなるのですが、上は赤のままなのです。 ペイントでキャンパスの大きさを100*100にしてから実行すると この場合、四角はすべて黒となります。 拙い説明で申し訳ありませんが、これでお分かりいただけたでしょうか? >>画像の大きさを画像自身からとるようにすればいいのでは? 汎用性を考え、当然その考えは持ちました。 しかしながら、画像処理に関する知識がないため、やりたくてもできないのが現状です。 よろしければ画像の大きさを画像自身から取得する方法をご教示ください

関連するQ&A

  • バイナリファイル(画像)のよみこみ

    レポートで1024×1024ピクセルの画像を、間引いて256×256の画像にしろというのが出されました。画像はrawファイルです。 それで、とりあえず画像を読み込んで、出力するプログラムを書いてみたんですが、コンパイルは出来るのに実行すると不正な処理とけいこくがでてきてしまいます。 ソースは #include<stdio.h> main() { unsigned char in[1024][1024],out[1024][1024]; FILE *fp; int i,j; fp=fopen("aaa.raw","rb"); fread(in,sizeof(unsigned char),1024*1024,fp); fclose(fp); for(i=0;i<1024;i++){ for(j=0;j<1024;j++) out[i][j]=in[i][j]; } fp=fopen("bbb.raw","wb"); fwrite(out,sizeof(unsigned char),1024*1024,fp); fclose(fp); } です。 どこがいけないのかアドバイスいただきたいです。よろしくお願いします。

  • プログラム(C)

    #include <stdio.h> #include <stdlib.h> #define FNAME "smp.bmp" #define WSIZE 256 #define HSIZE 256 #define BSIZE 1024 int main(void) { struct BMPFILEHEADER { ・   ・ }; struct BMPINFOHEADER { ・   ・ }; unsigned char img[HSIZE][WSIZE][3]; unsigned char buf[BSIZE]; struct BMPFILEHEADER lpHead; struct BMPINFOHEADER lpInfo; FILE *fp; int i; int j; int k; fp = fopen(FNAME,"rb"); if (fp==NULL) { printf("ファイルをオープンできません\n"); return 0; } fread(&lpHead.bfType, sizeof(unsigned short),1,fp); fread(&lpHead.bfSize, sizeof(unsigned int),1,fp); fread(&lpHead.bfReserved1, sizeof(unsigned short),1,fp); fread(&lpHead.bfReserved2, sizeof(unsigned short),1,fp); fread(&lpHead.bf0ffBits, sizeof(unsigned int),1,fp); fread(&lpInfo, sizeof(struct BMPINFOHEADER),1,fp); for(i=0;i<HSIZE;i++) { fread(buf,sizeof(unsigned char),WSIZE*3,fp); for(j=0;j<WSIZE;j++) { for(k=0;k<3;k++) { img[HSIZE-1-i][j][k]=buf[j*3+k]; } } } fclose; return 0; } このプログラムはBMP画像を読み込むプログラムなんですが このプログラムに画素値を出力するプログラムにしたいのですがうまくできません。 結果は(真っ白な画像の時)255255255・・・255255と出力したいのです。白黒画像なのでR=G=Bで1画素値は255だけでいいのですが。どうしても255255255や25500などとでてしまいます。 アドバイスお願いします。(800字までなので構造体の宣言は抜いてしましました) 。

  • 画像を読み込んでヒストグラムを作るプログラム

    2値化画像を読み込んで、ヒストグラムを表示させるプログラムを作りたいのですが、 以下のソースを作成したのですが実行中にエラーが発生して困っています。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #define width 640 #define height 480 int main(int argc, char* argv[]) { unsigned char image[640*480]; unsigned char header32[1078];//ビットマップ情報 int i; int *histogram; FILE *fp1; unsigned char buffer1[640*480]; for(i=0; i<640*480; i++) { image[i]=0; buffer1[i]=0; } fp1=fopen("koshimizu1.bmp","rb"); // fread(image,1,640*480,fp1); fread(header32,1,1078,fp1); fread(buffer1,width,height,fp1); fclose(fp1); for(i=0;i<256;i++){ histogram[i]=0; } for(i=0;i<640*480;i++){ histogram[image[i]]++; } for(i=0;i<256;i++){ printf("%d %d \n",i,histogram[i]); } return 0; }

  • C言語でクロマキー合成をする方法

    input.bmpとbackground.bmpとoutput.bmpを作りで好きな絵を用意して、input.bmpというビットマップファイル(色数は24ビット)とbackground.bmpというファイルを開き,クロマキー合成をし,ビットマップファイルoutput.bmpに出力させる。 上記の物をC言語でするにはどうすればいいのでしょうか? 下記のものは自分でやったのですがやり方が分かりません。どなたか知恵を貸してください。 (ほとんど間違っていると思いますが・・・) #include<stdio.h> int main() { FILE *fp; int i; char data[2]; short s; fp1=fopen("input.bmp","rb"); fp2=fopen("background.bmp","rb"); fp3=fopen("output.bmp","wb") int k; for(k=0;k<10000;k++){ fputc(0,fp); fputc(0,fp); fputc(0,fp); } fclose(fp); fread(&data[0],1,2,fp1); fread(&data[0],1,2,fp2); fwrite(&data[0],1,2,fp3); int fs; fread(&fs,f1); fread(&fs,f2); fwrite(&fs,f3); fp=fopen("aka.bmp","wb"); fread(moji,1,2,fp); i=30054; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); i=54; fread(&i,4,1,fp); i=40; fread(&i,4,1,fp); i=100; fread(&i,4,1,fp); i=100; fread(&i,4,1,fp); s=1; fread(&s,2,1,fp); s=24; fread(&s,2,1,fp); i=0; fread(&i,4,1,fp); i=30000; fread(&i,4,1,fp); i=120; fread(&i,4,1,fp); i=120; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); for(k=0;k<10000;k++){ fputc(0,fp); fputc(0,fp); fputc(70,fp); } fclose(fp); fp=fopen("midori.bmp","wb"); fread(moji,1,2,fp); i=30054; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); i=54; fread(&i,4,1,fp); i=40; fread(&i,4,1,fp); i=100; fread(&i,4,1,fp); i=100; fread(&i,4,1,fp); s=1; fread(&s,2,1,fp); s=24; fread(&s,2,1,fp); i=0; fread(&i,4,1,fp); i=30000; fread(&i,4,1,fp); i=120; fread(&i,4,1,fp); i=120; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); for(k=0;k<10000;k++){ fputc(0,fp); fputc(150,fp); fputc(0,fp); } fclose(fp); fp=fopen("ao.bmp","wb"); fread(moji,1,2,fp); i=30054; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); i=54; fread(&i,4,1,fp); i=40; fread(&i,4,1,fp); i=100; fread(&i,4,1,fp); i=100; fread(&i,4,1,fp); s=1; fread(&s,2,1,fp); s=24; fread(&s,2,1,fp); i=0; fread(&i,4,1,fp); i=30000; fread(&i,4,1,fp); i=120; fread(&i,4,1,fp); i=120; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); i=0; fread(&i,4,1,fp); for(k=0;k<10000;k++){ fputc(255,fp); fputc(0,fp); fputc(0,fp); } fclose(fp); return(0); }

  • C言語で.pgmの画像を作り、見る

    Windows10のコマンドプロンプト上でC言語を使って.pgmの画像を作り、見ることができないので質問します。 以下のソースコードを実行してつくった。out.pgmファイルをGIMPとirfanviewというソフトを使ってみようとしましたが、GIMPはPNM 画像 エラーメッセージ 不正なファイルですと返し、irfanviewは invalid or unsupported PNMファイルと返し、何も表示されませんでした。 #include<stdio.h> int main(void){ FILE *fp; fp=fopen("out.pgm","wb"); fprintf(fp,"P5\n"); fprintf(fp,"#Image\n"); fprintf(fp,"256 256\n"); fprintf(fp,"255\n"); for(int i=0;i<256;i++){ for(int j=0;j<256;j++){ fwrite(&j,sizeof(unsigned char),1,fp); } } fclose(fp); return(0); } どなたかC言語で.pgmの画像を作り、見る方法を教えてくださいお願いします。

  • C言語でファイル読み書きを早くしたい。

    いつも利用させてもらって助かっています。 あるプログラムを作成しているのですが、ファイル入力の部分がネックとなってしまって、全体が使いものにならない状況に陥っています。 たくさんのデータをfread1回で読み込むことにより、読み込み速度はずいぶんと改善されましたが、まだ圧倒的に遅い状況です。システムコールを使いましたが、ほとんど改善されませんでした。 読み込み/書き込みの速度を改善する方法として,SSDメモリを使ったりする方法があると思いますが,プログラムの観点から改善できるところはないでしょうか? 下に、ファイル読み込みの部分だけ記述したコードを添付させて頂いたので、改善できる点があれば、御指摘頂けると助かります。 なお、前提として, (1)データはスタック領域だと不足するので、ヒープ領域に確保 (2)データファイルは改行無しの一連のデータ とします。 ちなみに、環境は OS   : CentOS5.3 memory   : 6GB コンパイラ : gcc です。 よろしくお願いします。 //----------------------------------------------------- //通常バージョン #include <stdio.h> #include <stdlib.h> #define SIZE (512*1024*1024) //500MB int main(void) { unsigned long int i; unsigned char *data; FILE *fp; data = (unsigned char *)malloc(SIZE); if(data == NULL) { printf("メモリが確保できません\n"); exit(EXIT_FAILURE); } fp = fopen("filein.dat", "rb"); fread( data, sizeof( unsigned char), (int)SIZE, fp ); fclose(fp); /* //表示 for( i=0; i<SIZE; i++ ){ printf("%2x", data[i]); } puts(""); */ fp = fopen("fileout.dat", "w"); fwrite( data, sizeof( unsigned char), (int)SIZE, fp); fclose(fp); free(data); return 0; } //----------------------------------------------------- //readシステムコールを使ったバージョン #include <stdio.h> #include <stdlib.h> #define SIZE (512*1024*1024) //500MB int main(void) { unsigned long int i; unsigned char *data; data = (unsigned char *)malloc(SIZE); if(data == NULL) { printf("メモリが確保できません\n"); exit(EXIT_FAILURE); } int fd; fd = open( "filein.dat" ); read( fd, data, sizeof(unsigned char)*SIZE); close(fd); /* //表示 for( i=0; i<SIZE; i++ ){ printf("%2x", data[i]); } puts(""); */ FILE *fp; fp = fopen("fileout.dat", "w"); fwrite( data, sizeof( unsigned char), (int)SIZE, fp); fclose(fp); free(data); return 0; }

  • 画像処理について・・・・・・・・・・・

    #include<stdio.h> #include<stdlib.h> #define X_SIZE 512 #define Y_SIZE 512 unsigned char DATA[Y_SIZE][X_SIZE]; unsigned char O_DATA[Y_SIZE][X_SIZE]; char input_file_name[256]=”Lenna.raw”; char output_file_name[256]=”Lenna_out.raw”; void heikin(){ int x,u; int temp; for(y=1;y<Y_SIZE-1;y++){ for(x=1;x<X_SIZE-1;x++){ temp=・・・・・・・・・・・・・・・・・・・・・・・・; O_DATA[x][y]=(unsigned char)temp; } } } Int main (){ FILE*fp; If((fp=fopen(input_file_name,”rb”))==NULL){ Printf(“ファイルオ-プンエラ-\n”); Return 1; } Fread(DATA,sizeof(DATA),1,fp); fclose(fp); heikin(); if((fp=fopen(output_file_name,”wb”))==NULL{ printf(“ファイルオ-プンエラ-\n”); return 1; } Fwrite(O_DATA,sizeof(O_DATA),1,fp); Fclose(fp); Return 0; } ソースコードをやっているのですが、後、・・・・・・・・・の所を入力して完成なんですが、苦戦してます。 処理の内容としましては、 1、入力画像Lenna.rawを読み込んで、 2、平均値フィルタをかけ、 3、Lenna_out.rawに書き出す(保存する)したいんですが、公式みたいなのを入れればいいのでしょうか? すみませんが、お願いします。

  • fread処理がうまくいかない!!

    バイナリエディタでfwriteで書き込んだデータは確認できたのですがfread後のデータがきちんと表示されません。 どうしてでしょうか? #include <stdio.h> void main(void) { char i[] = {'a','b'}; char j[2]; FILE *fpbin; fpbin = fopen("data","wb+"); fwrite(&i,sizeof(char),2,fpbin); fpbin = fopen("data","rb"); fread(&j,sizeof(char),2,fpbin); printf("j = %c\n", j[0]); fclose(fpbin); }

  • c言語での wavファイルの編集(音楽編集・フェード)

    プログラミング初心者です。 現在Cでwavファイルの編集を行っています。 wavファイルにフェードをかけようと思うのですが、8bitの場合はうまくいったのですが、16ビットの場合がうまくいきません。 2バイト分読み込むだけでいいと思って、8ビットのときのf***(&data,1,***);のところの1を2にしただけです。 以下のようにプログラムを作成したのですがだめでした。 ヘッダの情報は決めうちでそのまま書き込むようにしてあります。 どのようにしたらうまくいきますか?? アドバイスよろしくお願いします。 #include<stdio.h> #include<stdlib.h> #include<math.h> #define HEADER 44 // HEADER SIZE #define F_LEVEL 0.9999999 // FADE LEVEL double FADE(double f); main(int argc, char *argv[]) { FILE *f_in,*f_out; unsigned char header[HEADER]; unsigned char data2[2]; int data; double work,mul=1.0; if((f_in = fopen(argv[1],"rb")) == NULL) exit(0); if((f_out = fopen(argv[2],"wb")) == NULL) exit(0); fread(header,1,HEADER,f_in); // HEADER READ fwrite(header,1,HEADER,f_out); // HEADER WRITE while(fread(data2,2,1,f_in) == 1)<-ここのwhile内の部分 {                   をどうにかすればいいと思うのですが・・・ work = data2[0]+256U*data2[1]; mul = FADE(mul); work = work * mul; data = (int)(work); fwrite(&data,2,1,f_out); } data = 0; fwrite(&data,2,1,f_out); data = 0; fwrite(&data,2,1,f_out); fclose(f_in); fclose(f_out); } double FADE(double f)// FADE { f = f * F_LEVEL; return (f); } よろしくお願いします。 参考URL:http://www.kk.iij4u.or.jp/~kondo/wave/

  • Ç言語でファイルサイズを変更するプログラム

    Ç言語初心者です。visualstudio2010を使用しています。 ファイルサイズ100MBのtest.binをバイナリモードで開き、10GBになるまで0を追加するプログラムを組みたいと思います。 ファイルを読み込んで出力するようには組めたのですが、この手法だとファイルサイズが大きいと時間がかかってしまいます。 現在のソースは以下の様になっているのですが、どうしたらもっと早く終わらせることが出来るでしょうか? また、int型でファイルサイズを取得していますが、ファイルサイズがもっと大きくなったときにint型では足りなくなってしまうのもどうすればいいのか困っています。 ※元ファイルサイズ(test.bin)は例としています。今後?GBサイズになると思います。変更後のファイルサイズは今後10GBくらいまでで考えています。 #include <stdio.h> #include <string.h> #include "stdafx.h" #define KIRO (1024) #define MEGA (KIRO*1024) #define GIGA (MEGA*1024) #define SIZE (100) int main(void) { FILE *fp,*fpw; unsigned char c; unsigned char zero = 0; int i = 0; int filesize; // 元ファイルをバイナリモードで開く fp = fopen( "test.bin", "rb" ); if( fp == NULL ) { printf( "test.binが開けません" ); return 1; } fseek( fp, 0, SEEK_END ); filesize = ftell( fp ); fseek( fp, 0, SEEK_SET ); // 書込み先をバイナリモードで開く fpw = fopen( "test_W.bin", "wb" ); if( fp == NULL ) { printf( "test_W.binが開けません" ); return 1; } while(1) { i++; // 指定サイズになったら終了 if(i > MEGA * SIZE) break; // ファイルサイズまで読み書き if(filesize < i){ // 残りを0で代入 fwrite(&zero, sizeof(unsigned char), 1, fpw); /* 1文字ずつ書き込み */ }else{ // ファイルの内容を1文字ずつ読み書き fread( &c, sizeof(unsigned char), 1, fp ); /* 1文字ずつ読み込み */ fwrite(&c, sizeof(unsigned char), 1, fpw); /* 1文字ずつ書き込み */ } printf( "%d番目\n", i ); } printf( "\n" ); fclose(fp); fclose(fpw); return 0; }

専門家に質問してみよう