研究にまるで関係ないけど、今までやったことがない画像処理に2日間研究そっちのけで取り組んでみた。
と言ってもJPEGの仕組みを知るにとどまりましたがw
やろうとしたことは、画像サイズを取得して縮小すること。ということでまずは画像サイズ取得が必要で、JPEGの構造を知る必要がありました。
今回参照にしたのは下記のリンク
JPEG画像形式の概要(フォーマット) - ウェブで用いられる画像形式。
http://siisise.net/jpeg.html
JPEG画像の構造
JPEG画像の情報はセグメントと呼ばれるいくつかのブロック
に分かれており、各セグメントの開始となる2バイトのデータをマーカと呼びます。マーカの1バイト目は0xFFの値となっています。
目的の縦、横の大きさがあるセグメントはSOFというセグメント。マーカが0xFFC0のものを探します。
ここで気を付けるべきは(ここでハマった)、SOFセグメントを見つけるまでに、FFC0の並びが存在しうるということ。
これを回避するための対策は、セグメント中のデータをスキップすること。セグメントのデータサイズはマーカの次の2バイト分に示されているので、それを読み込んでバイト数分スキップ。下記リンク先に詳しいことが載っています
ソースコード例
Cで縦、横を取得して表示するだけのプログラム例を示します。
int main() { char* path="test.jpg"; unsigned char byte[8]; unsigned char c; unsigned int width,height; JpgSize(path,&width,&height); FILE* file; errno_t e = fopen_s(&file,path,"rb"); fread(byte,1,2,file); // SOIセグメントを読む if(byte[0]!=0xff || byte[1]!=0xd8) return-1; while(true) { fread(byte,1,2,file); if(byte[0]==0xff) { // マーカの確認 if(byte[1]==0xc0 || byte[1]==0xc2) { // SOFセグメントならば読み込み fread(byte,1,3file); // 3バイト目までは不要 fread(byte,1,4,file); width = ((unsigned int)byte[2]<<8)|byte[3]; // 横 height = ((unsigned int)byte[0]<<8)|byte[1]; // 縦 break; } else { fread(byte,1,2,file); // 他のセグメントデータは読み飛ばす unsigned int len = ((unsigned int)byte[0]<<8)|byte[1]; len-=2; // 長さを表すデータはすでに読んでいる while(len>0) { getc(file); len--; } } } printf("w:%d h:%d\n",width,height); fclose(file); return 0; }
- 作者: B.W.カーニハン,D.M.リッチー,石田晴久
- 出版社/メーカー: 共立出版
- 発売日: 1989/06/15
- メディア: 単行本
- 購入: 28人 クリック: 721回
- この商品を含むブログ (200件) を見る
画像縮小はまた今度。