普通のファイルを画像にしたり、その画像からファイルに戻したりしたら面白いだろうなぁ
と思っていたので、今BMPにするものを書いてみました。
#include <stdio.h> #include <stdlib.h> #include <math.h> #include "bmp.h" main(int argc, char** argv) { FILE *fp; fpos_t sz; int v, cnt; if(argc < 2) { exit(1); } if((fp = fopen(argv[1],"r")) == NULL) { exit(1); } cnt = 0; //Get File size fseek( fp, 0, SEEK_END ); fgetpos( fp, &sz ); printf("file size: %d\n",sz); fseek( fp, 0, SEEK_SET ); int *data; data = (int *)malloc(sizeof(int) * sz); printf("---------------------------\n"); while((v = fgetc(fp)) != EOF) { data[cnt] = v; cnt++; } printf("\n---------------------------\n"); printf("Count: %d\n", cnt); int i,j; for(i = 0; i < cnt; i++) { printf("%d ",data[i]); } printf("\n---------------------------\n"); //Find width height int width = floor(sqrt(cnt)); double h = (double)cnt/(double)width; for(; (double)floor(h) != (double)h; --width, h = (double)cnt/(double)width) { } printf("width: %d\n",width); printf("height: %lf\n",h); img *tmp; tmp = (img *)malloc(sizeof(img)); tmp->height = h; tmp->width = width; for(i = 0; i < tmp->height; i++) { for(j = 0; j < tmp->width; j++) { int val = data[i * (tmp->width) + j]; tmp->data[i][j].r = val; tmp->data[i][j].g = val; tmp->data[i][j].b = val; } } WriteBmp("img.bmp",tmp); fclose(fp); free(data); free(tmp); return 0; }
こちらが画像ファイルにするプログラムです
BMPを書き出す処理は
C言語による画像処理プログラミング
こちらのbmp.{c|h}を利用させていただいております。
次が復元するプログラムです
#include <stdio.h> #include <stdlib.h> #include <math.h> #include "bmp.h" main(int argc, char** argv) { if(argc != 3) exit(1); img *tmp; tmp = (img *)malloc(sizeof(img)); ReadBmp(argv[1], tmp); int size = tmp->width * tmp->height; int *data = (int *)malloc(sizeof(int) * size); int i, j; for(i = 0; i < tmp->height; i++) { for(j = 0; j < tmp->width; j++) { data[i * tmp->width + j] = tmp->data[i][j].r; } } FILE *fp; if((fp = fopen(argv[2], "w")) == NULL) { exit(1); } for(i = 0; i < size; i++) { fputc(data[i], fp); } fclose(fp); free(data); free(tmp); }
こんな感じです。
このプログラムソースじたいをかけてみると
このようなグレースケールの画像になります(0~255)で都合がよかったので
そして復元すると
#include <stdio.h> #include <stdlib.h> #include <math.h> #include "bmp.h" main(int argc, char** argv) { FILE *fp; fpos_t sz; int v, cnt; if(argc < 2) { exit(1); } if((fp = fopen(argv[1],"r")) == NULL) { exit(1); } cnt = 0; //Get File size fseek( fp, 0, SEEK_END ); fgetpos( fp, &sz ); printf("file size: %d\n",sz); fseek( fp, 0, SEEK_SET ); int *data; data = (int *)malloc(sizeof(int) * sz); printf("---------------------------\n"); while((v = fgetc(fp)) != EOF) { data[cnt] = v; cnt++; } printf("\n---------------------------\n"); printf("Count: %d\n", cnt); int i,j; for(i = 0; i < cnt; i++) { printf("%d ",data[i]); } printf("\n---------------------------\n"); //Find width height int width = floor(sqrt(cnt)); double h = (double)cnt/(double)width; for(; (double)floor(h) != (double)h; --width, h = (double)cnt/(double)width) { } printf("width: %d\n",width); printf("height: %lf\n",h); img *tmp; tmp = (img *)malloc(sizeof(img)); tmp->height = h; tmp->width = width; for(i = 0; i < tmp->height; i++) { for(j = 0; j < tmp->width; j++) { int val = data[i * (tmp->width) + j]; tmp->data[i][j].r = val; tmp->data[i][j].g = val; tmp->data[i][j].b = val; } } WriteBmp("img.bmp",tmp); fclose(fp); free(data); free(tmp); return 0; }
とちゃんと復元されているのがわかります。
BMPだけでなくPNGやJPEGやらGIFに対応させたり
複数のファイルだったらGIFアニメにしたりとやってみたいと思っています。