今週は,エディタで開くとぐちゃぐちゃになっていたバイナリファイルについて説明します.
(復習)ファイルには,大きく分けて二種類あります.
バイナリファイルのうち,よく使う画像ファイルを扱おう.
バイナリファイルも,テキストファイルと操作の基本は同じです.
注意するのは,ファイルを開くときに,バイナリファイル形式で開く必要があります.
fp = fopen(filename, "rb");
データの読み込みには fread,書き込みにはfwrite という関数を用います.
#include <stdio.h> void main() { FILE *fp; char filename[] = "bintest.dat"; int buf_w[10], buf_r[10]; int i; for(i=0; i<10; i++){ buf_w[i] = (i+1) * 10; } if((fp = fopen(filename, "wb")) == NULL){ printf("ファイルを作れません"); return; } fwrite(buf_w, sizeof(int), 10, fp); fclose(fp); if((fp = fopen(filename, "rb")) == NULL){ printf("ファイルを開けません"); return; } fread(buf_r, sizeof(int), 10, fp); fclose(fp); for(i=0; i<10; i++){ printf("%d\n", buf_r[i]); } }
演習
画像データ(test.dat)を画面に表示するプログラムを,次のプログラムを元に完成せよ.
//bmpファイルのヘッダを取り除いたファイルの表示 #include <stdio.h> #include "mogra_rgb.f" int main(void) { unsigned char *image; FILE *fp; int xsize=500, ysize=546; int i,j; char filename[128]="test.dat"; image = (unsigned char *)malloc((size_t)xsize*ysize*3); if (image == NULL) { printf("--memory allocation error !\n"); return -1; } if ((fp = fopen(filename, "rb")) == NULL) return -1; fread(image, sizeof(unsigned char), (size_t)(long)xsize*ysize*3, fp); fclose(fp); g_int(xsize, ysize); /* ここを考える */ gend(); free (image); return 0; }
配列へのデータの読み込みにはポインタを利用し,これまでのように一旦普通の変数に読み込んでから配列に代入するというような面倒なことはしていません.
配列の大きさも,プログラムの中でmalloc関数(メモリを確保する関数)を用いて動的に行っています.(配列の大きさを自由に変えられる)
グラフィックの表示には,mogra_rgb.fというファイルを用いる.このプログラムの中で,
rgb_pset(x座標, y座標i, Rの値, Gの値, Bの値);
という関数が定義されているので,これを用いる.
Windwosで写真などを保存するのに一般に用いられている,BMP形式の画像ファイルは,ヘッダ付きのビットマップ形式のデータです.データは,画面の左から右,下から上へ保存され,B,G,Rの順番で各点の値が並んでいます.(情報処理1でやったんですが…,覚えてますか) この演習で用意したデータは,ヘッダ部分を削ったもので,サイズの情報などが入っていません.BMP形式の扱いは次回のお楽しみ.