デジカメ画像の撮影日時を秒まで取得


濱のオジーさん  2007-09-01 02:35:57  No: 27599

お世話になります。
カメラ画像を整理するために撮影日時を取得したいと考えています。WEBで調べましたら下記の方法で取れるようなので試しましたが  '2007/06/06 17:00'  のように分単位しか取得できないことがわかりました。このようなやりかたで秒単位まで取得する方法があったら教えてください。

    FilePath := ExtractFileDir(picfile);
    FileName := ExtractFileName(picfile);

    ObjShell := CreateOleObject('Shell.Application.1');
    ObjFolder := ObjShell.NameSpace(OleVariant(FilePath));
    ObjFolderItem := ObjFolder.ParseName(FileName);
    
    i:=25;  strdate:=ObjFolder.GetDetailsOf(ObjFolderItem, i);


通りすがり  2007-09-01 19:59:39  No: 27600

これでいかが?

procedure TForm1.Button1Click(Sender: TObject);
var
  datetime1:TdateTime;
  sr: TSearchRec;
  sTime : TSystemTime;
  lTime : TFileTime;
begin
  flnm:='hoge.jpg';

  if FindFirst(flnm, 0, sr) = 0 then begin
    FileTimeToLocalFileTime(sr.FindData.ftCreationTime, lTime);
    FileTimeToSystemTime(lTime, sTime);
    datetime1 := EncodeDate(sTime.wYear, sTime.wMonth, sTime.wDay) +
              EncodeTime(sTime.wHour, sTime.wMinute, sTime.wSecond, sTime.wMilliseconds);
    Label.Caption := FormatDateTime('yyyy/mm/dd hh:nn:ss',datetime1);
  end;

end;


濱のオジーさん  2007-09-01 21:43:15  No: 27601

通りすがり様  ご回答をありがとうございました。  早速実験させていただきました結果は表示される日付はどうも撮影日時でもファイル作成、更新日時でもなさそうです。  最初の質問時に書かせていただいたソースは
http://www.geocities.jp/fjtkt/problems/2006_0019.html
を参考に要所だけ取り出したもので、これで時:分までの撮影日時が取れるのですが秒まで必要になり質問させていただいたものです。よろしくお願いします。


えーと  2007-09-01 22:56:05  No: 27602

ファイルの日時じゃなくて Exif 情報の取得ですよね。
以前はコンポーネントがあったようですが、今は知りません。
Google で検索してみるとたくさん例がありますが、簡単ではありませんね。


濱のオジーさん  2007-09-02 02:28:44  No: 27603

えーと様、ご回答をありがとうございます。

>ファイルの日時じゃなくて Exif 情報の取得ですよね。
やはりEXIFでないとだめでしょうか?  EXIFに関しましては一度コンポーネントを下記よりDLして試したのですがどうもエラーが出てしまい当方の環境(D6パーソナル)では動かないので何とか違う簡単な方法がないかさがしていたものです。
http://wblue.web.infoseek.co.jp/com/exifinfo/top.htm
必要な情報は画像サイズと撮影日時(秒までほしい)だけなので簡単な方法に飛びついたわけですがやはりEXIFを読まないとだめでしょうか?

何か方法、または参考になる情報がありましたらよろしくお願いします。


えーと  2007-09-02 11:29:41  No: 27604

いま、Del6Personal がないので後で試して見ます。
まえの BlueLeaf さんのコードもシェルを使って Exif 情報を見てるんですね。

厳密にやるとおもしろいので、ちかじか試してみようと思っていますが、
いまはDelphiの環境がないので、コードをしめすことができません。

個人的にも興味があるので、来週あたりにやってみようと思っています。


濱のオジーさん  2007-09-02 19:39:46  No: 27605

えーと様、ご回答をありがとうございます。

ExifInfoを当方で試した結果を申しますと当方で過去にDLしているものはバージョンがExifInfo30000、30100、30101の3種あり30000は当方でも通りました。しかしEXIFデータがない場合コンポーネントの中でMessageBoxが開いて止まってしまうのでバッチ処理ができない、とか他のソフト(当方がVBでコピペして作ったもの)では撮影日時が出るのにこれではExifデータがないとのメッセージが出て撮影日時を取得できない、などの問題がありました。

とりあえず画像サイズと撮影日時を簡単に取りたいというものです。

>個人的にも興味があるので、来週あたりにやってみようと思っています。

大いに期待しています。できましたら宜しくお願いします。


ヘルプは飾り物?  2007-09-02 20:50:26  No: 27606

画像ファイルがExif規格やDCF規格に準拠しているかどうかを検査する関数は用意されているよ。
D6でエラーが出るのは未対応だから仕方がないね。
適当なresourcestring書いておいたら?
  resourcestring SFOpenErrorEx = 'MzWideFileStreamOpenError: %s';


濱のオジーさん  2007-09-03 02:47:43  No: 27607

ヘルプは飾り物?様、ご回答をありがとうございました。ご指摘の通りエラーがハイライトされたのは@SFOpenErrorExという箇所でした。コンポーネントというものは初めてですので当方のインストール方法、使用方法などに自信が持てずに早々に退却してしまいましたがExifsample(というものが以前ありました)+ExifInfo30000で試したところでは大変強力なToolであることはわかりました。resourcestring SFOpenErrorEx = 'MzWideFileStreamOpenError: %s';
をどこに書いたら良いか?などお恥ずかしいながら分かりませんがあちこちに書いてみて試行錯誤でトライしてみたいと思います。ヒントをありがとうございました。行き詰ったところでまたご教示をお願いします。


ちょっと通りますね  2007-09-15 11:52:31  No: 27608

>EXIFデータがない場合コンポーネントの中でMessageBoxが開いて止まってしまう

ExifInfoのヘルプでTExifInfoクラスのOnErrorイベントを読めば幸せになれるかも。

>他のソフト(当方がVBでコピペして作ったもの)では撮影日時が出るのに
>これではExifデータがないとのメッセージが出て撮影日時を取得できない

Exifが取得できない画像はAPP1マーカー(Exif)の位置が通常と違うかもしれません。
画像ソフトのせいでAPP0マーカー(JFIF)が挿入されてしまって、
ExifとJFIFが混在することが良くあるようです。
JpegAnalyzerで簡単に確認するとができます。

ExifInfoではこのようなケースだとExifデータが取得できないようです。
ちゃんとAPP1マーカーを探す関数はExifInfo.pasにあるのですが、
残念なことに正常に機能していません。

で、ExifInfo.pas内の関数FindApp1Marker()を1箇所次のように修正してみたら、
あっさり解決しました。

    if BufByte = $E1 then BufWord := Exif_APP1
        else Image.Seek(-1, soCurrent);  //ここの引数「-1」を「1」にする

たぶんVer.30000でも大丈夫だと思います。


BlueLeaf1336  2007-11-11 05:56:41  No: 27609

2ヶ月以上たっているので読んでもらえるかどうかわかりませんが
自分の名前が出てきてたのと、秒まで取得できることを確認できたので
報告しておきます。

確かに
http://www.geocities.jp/fjtkt/problems/2006_0019.html
のやり方だと分までしか取れません。(2007/03/31 12:53 のように)

ただ、
http://www.geocities.jp/fjtkt/problems/2006_0020.html
の方法で、
SCID に
http://www.geocities.jp/fjtkt/problems/2006_0021.html
の「写真の撮影日」にあたる {F29F85E0-4FF9-1068-AB91-08002B27B3D9} 12
を指定してやると秒まで取れます。

こちらの環境は
WindowsXP Home + WindowsUpdate全部
Delphi6 Personal 全パッチ適用済み
です。
(先ほどと同じ写真に対して実行すると 2007:03:31 12:53:42 のように)

以下テストしたソースです。
ボタンをクリックすると、実行ファイルの入っているフォルダの中のすべての
ファイルに対して撮影日を調べます。
ファイル数が多いフォルダの中では実行しないほうが良いと思います。

どうでしょうか?

uses
    ComObj;

procedure TForm1.Button1Click(Sender: TObject);
var
    Shell: OleVariant;
    Folder: OleVariant;
    FolderItems: OleVariant;
    ItemCount: Integer;
    i: Integer;
    FolderItem: OleVariant;
    SCID: String;
    Value: OleVariant;
begin
    //  Shellオブジェクト取得
    Shell := CreateOleObject('Shell.Application');

    //  起動フォルダのFolderオブジェクト取得
    Folder := Shell.NameSpace(OleVariant(ExtractFilePath(ParamStr(0))));

    //  その全てのアイテムにアクセスするためのFolderItemsオブジェクト取得
    FolderItems := Folder.Items;

    //  アイテム数
    ItemCount := FolderItems.Count;

    //  順番に
    for i := 0 to ItemCount - 1 do
    begin
        //  アイテム取得
        FolderItem := FolderItems.Item(i);

        //  拡張プロパティを取り出すための引数
        SCID := '{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 12';

        //  拡張プロパティの値を取り出す
        Value := FolderItem.ExtendedProperty(SCID);

        //  いろんな形式があるので文字列に変換して表示
        Memo1.Lines.Add('[写真の撮影日] ' + VarToStr(Value));
    end;

    //  解放
    FolderItem  := Unassigned;
    FolderItems := Unassigned;
    Folder      := Unassigned;
    Shell       := Unassigned;
end;


ドラン  2007-11-11 11:48:08  No: 27610

追試してみました。
結果。携帯で取った写真で機種により何も表示されないのがあったのと、

>http://www.geocities.jp/fjtkt/problems/2006_0019.html
>のやり方だと分までしか取れません。(2007/03/31 12:53 のように)

とおっしゃっていますが、31に同じデータが入っているようです。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加