プログラミングのメモ書きです。日記も兼ねてます。
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
よくデジカメなどで使われる「Exif」を読み込んでみます。
さて、Exifを読んでみようといたものの、僕自身Exifの知識がまったくありません(・ω・;)
そこで、Googleで検索してみたところ、ここを参考にすることにしました。>http://www.dinop.comの「Microsoft Visual C++ Tips集」<
ここを見る限りExifは、ファイルのはじめにExifの情報(ヘッダ)が付いていて、さらにその後ろに、各情報が繋がっているようです。
というわけで、今日は、ヘッダを読み込んでみようと思います。
ヘッダを読むといったって、結構情報を削除しますが、まぁ途中で拾うことが出来るでしょう。(・ω・;)
で、読み込む流れですが。
1:ヘッダを全部読み込む
2:Exifデータであるか確認する
3:ヘッダの大きさを取得する
4:バイナリの形式を取得する
5:データの情報を取得する
で、行きます。
1:ヘッダを全部読み込む
12バイトほどですので全部一気に読んじゃいましょう。
"fread"関数を使うのが本当でしょうが、デバッグなどの関係で、"fgetc"をループで使っています。
//ヘッダ取得
for(i=0;i<0x10;i++){
//読み込み
Head[i]=fgetc(File);
}
何の変哲もないただのループです。(^ω^;)
2:Exifデータであるか確認する
今さっき読み込んだヘッダのうち、
「0x00バイト目->0x01バイト目が0xFF,0xD8」
「0x02バイト目->0x03バイト目が0xFF,0xE1」
「0x06バイト目->0x0Bバイト目が"Exif\0\0"」
ならば、Exifのデータらしいです。(一部異なるものがあるそうですが)
なので、単純に"if"で比較しています。
//Exifか確認
if(Head[0x00]!=0xFFFFFFFF || Head[0x01]!=0xFFFFFFD8)return -1;//SOIマーカーの確認
if(Head[0x02]!=0xFFFFFFFF || Head[0x03]!=0xFFFFFFE1)return -2;//APP1マーカーの確認
if(Head[0x06]!=0x45 || Head[0x07]!=0x78 || Head[0x08]!=0x69 || Head[0x09]!=0x66 || Head[0x0A]!=0x00 || Head[0x0B]!=0x00)return -3;//EXIFマーカーの確認
…アレ?0バイト目とかは「0x??」出ないのと思った方、すみません。なぜかこうしないとうまく動かないんです…(´・ω・`)
多分直しても大丈夫なんでしょうけど…
3:ヘッダの大きさを取得する
あとで読み込むときの頭出し用にヘッダの大きさを読み込んでおきます。
//ヘッダサイズを取得
size=(Head[0x04]<<8|Head[0x05])-6;
初めてビット演算をしてみました。
ちなみに、最後の"-6"は、"Exif\0\0"の分です。
4:バイナリの形式を取得する
どうやら、バイナリというのは「モトローラ」と、「Intel」の二つの形式があって、格納方法が違うようです。
そこで、読み込むとき用に保存しておきます。
//格納形式を取得
type=(Head[0x0C]==0x4D)?true:false;//trueならモトローラ
もし、0x0Cバイト目と、0x0Dバイト目が、"0x4D"(M)のときはモトローラーで、"0x49"(I)のときはインテル形式で格納しているようです。
5:データの情報を取得する
何個データがあるのかを取得しています。
0x14バイト目から2バイト読み込んで、組み合わせています。
ちなみに、例のバイナリの違いをモロに受けてますので、仕分けしています。
//ディレクトリ情報取得
for(i=0;i<0x08;i++){
//読み込み
Directry[i]=fgetc(File);
}
return (type)?Directry[4]<<8|Directry[5]:Directry[4]|Directry[5]<<8;
最後が"return ..".なのは、この部分を関数で実装しているからです。
大体こんなもんで最小限のことは大丈夫…だと思います(ォィ
ソースを乗っけておきますんでどうぞ。ダウンロード(zip)
そこで、Googleで検索してみたところ、ここを参考にすることにしました。>http://www.dinop.comの「Microsoft Visual C++ Tips集」<
ここを見る限りExifは、ファイルのはじめにExifの情報(ヘッダ)が付いていて、さらにその後ろに、各情報が繋がっているようです。
というわけで、今日は、ヘッダを読み込んでみようと思います。
ヘッダを読むといったって、結構情報を削除しますが、まぁ途中で拾うことが出来るでしょう。(・ω・;)
で、読み込む流れですが。
1:ヘッダを全部読み込む
2:Exifデータであるか確認する
3:ヘッダの大きさを取得する
4:バイナリの形式を取得する
5:データの情報を取得する
で、行きます。
1:ヘッダを全部読み込む
12バイトほどですので全部一気に読んじゃいましょう。
"fread"関数を使うのが本当でしょうが、デバッグなどの関係で、"fgetc"をループで使っています。
//ヘッダ取得
for(i=0;i<0x10;i++){
//読み込み
Head[i]=fgetc(File);
}
何の変哲もないただのループです。(^ω^;)
2:Exifデータであるか確認する
今さっき読み込んだヘッダのうち、
「0x00バイト目->0x01バイト目が0xFF,0xD8」
「0x02バイト目->0x03バイト目が0xFF,0xE1」
「0x06バイト目->0x0Bバイト目が"Exif\0\0"」
ならば、Exifのデータらしいです。(一部異なるものがあるそうですが)
なので、単純に"if"で比較しています。
//Exifか確認
if(Head[0x00]!=0xFFFFFFFF || Head[0x01]!=0xFFFFFFD8)return -1;//SOIマーカーの確認
if(Head[0x02]!=0xFFFFFFFF || Head[0x03]!=0xFFFFFFE1)return -2;//APP1マーカーの確認
if(Head[0x06]!=0x45 || Head[0x07]!=0x78 || Head[0x08]!=0x69 || Head[0x09]!=0x66 || Head[0x0A]!=0x00 || Head[0x0B]!=0x00)return -3;//EXIFマーカーの確認
…アレ?0バイト目とかは「0x??」出ないのと思った方、すみません。なぜかこうしないとうまく動かないんです…(´・ω・`)
多分直しても大丈夫なんでしょうけど…
3:ヘッダの大きさを取得する
あとで読み込むときの頭出し用にヘッダの大きさを読み込んでおきます。
//ヘッダサイズを取得
size=(Head[0x04]<<8|Head[0x05])-6;
初めてビット演算をしてみました。
ちなみに、最後の"-6"は、"Exif\0\0"の分です。
4:バイナリの形式を取得する
どうやら、バイナリというのは「モトローラ」と、「Intel」の二つの形式があって、格納方法が違うようです。
そこで、読み込むとき用に保存しておきます。
//格納形式を取得
type=(Head[0x0C]==0x4D)?true:false;//trueならモトローラ
もし、0x0Cバイト目と、0x0Dバイト目が、"0x4D"(M)のときはモトローラーで、"0x49"(I)のときはインテル形式で格納しているようです。
5:データの情報を取得する
何個データがあるのかを取得しています。
0x14バイト目から2バイト読み込んで、組み合わせています。
ちなみに、例のバイナリの違いをモロに受けてますので、仕分けしています。
//ディレクトリ情報取得
for(i=0;i<0x08;i++){
//読み込み
Directry[i]=fgetc(File);
}
return (type)?Directry[4]<<8|Directry[5]:Directry[4]|Directry[5]<<8;
最後が"return ..".なのは、この部分を関数で実装しているからです。
大体こんなもんで最小限のことは大丈夫…だと思います(ォィ
ソースを乗っけておきますんでどうぞ。ダウンロード(zip)
PR
この記事にコメントする