もっと詳しく

Android 端末で ファイル のコピー・移動時に、 タイムスタンプ が 上書き されてしまうことがあります(特にストレージを跨ぐ操作において)。ギャラリー系 アプリ で、時系列に並んでいたはずの画像 ファイル の並びが崩れてしまうのは、これがその大きな原因です。これを解決するために使っていた自作のスクリプトと、今後それに代わってくれることを期待する アプリ を紹介します。

ファイル名から日付時刻を復元

スマートフォンで撮影した画像や動画は、そのファイル名に日付時刻を表す文字列を含んでいることから、パターンマッチングで生成時の日付時刻を取得し、

touch

 コマンドによりファイルのタイムスタンプを修正する、自作のスクリプトを使っていました。

あくまで自分の使う特定の機器で使えるようにしただけなので、以下のように対象フォルダ、対象ファイル名、

touch

 コマンドを内包しているBusyBoxのパスなど、全て決め打ちになっているので、移植の際はその環境に適宜合わせる必要があります。

#!/system/bin/sh
# Correct File Timestamp by Filename
# IMG_YYYYMMDD_HHMMSS.jpg / YYYYMMDD_HHMMSS.jpg

wpaths=("/sdcard/_TRANS/" "/storage/####-####/_TRANS/")
patterns=("IMG*.*g" "VID*.*" "2*.*g")

touch_by_patterns () {
    for p in ${patterns[@]}; do
        y=4; h=13; s=17
        if [ ${p:0:1} == 2 ]; then
            y=0; h=9; s=13
        fi

        ls ./$p > /dev/null 2>&1
        if [ $? -ne 0 ]; then
            echo "NO FILES: $wpath$p"
        else
            TZ=UTC-8 /data/busybox/busybox touch -t ${p:$y:8}${p:$h:4}.${p:$s:2} $p
            (( n++ ));
        fi
    done
    if [ $n -ne 0 ]; then
        echo "$n FILES CORRECTED: $wpath"
        #stat -c "%y %n" ./* | sed -e 's/\/.*\///' -e 's/\.000000000//'
        stat -c "%y %n" * | sed -e 's/\.000000000//'
    fi
}

for wpath in ${wpaths[@]}; do
    if [ -e $wpath ]; then
        n=0
        cd $wpath
        touch_by_patterns
    else
        echo "NO DIR: $wpath"
    fi
done

このスクリプトは、特にAndroidスマートフォンで生成される、exifメタデータを持たない動画ファイルのタイムスタンプを修正するのに重宝しました。

尚、連写時に同じ日付時刻で複数画像が生成されることになる為、例えば

IMG_20201120_112233_2.jpg

のように後ろに添え番がついてしまっても、問題なく日付と時刻を取り出して

touch

することが可能です。

 

exifメタデータを無理やり読んで復元

デジカメの画像をWiFi連携アプリを通じてAndroid端末内へ取り込んだ場合、その画像ファイル名は連番であることからオリジナルの日付時刻を得るにはexifメタデータを参照するしかありません。

Linuxではexiftoolを導入することでexifの内容を容易に参照することが可能ですが、Androidでは導入へのハードルも高いことから、こうした画像ファイル向けに、exifデータの収められたバイナリデータの先頭部分を力技で読み込むスクリプトも作ってみました。

head

コマンドにより一行抜き出して読み取りを試行するのですが、撮影デバイスによって撮影日時の収納位置が微妙に異なるため、「撮影日時がありそうな行」を一つずつ抜き出しては、日付時刻のパターンマッチングにかけるという、かなり強引なことをしています。

#!/system/bin/sh
# Correct File Timestamp by Exif Date

patterns=".jpg .JPG"
wpaths=("/sdcard/_TRANS/" "/storage/####-####/_TRANS/")
regex="[A-Z]"

for wpath in ${wpaths[@]}; do
    if [ -e $wpath ]; then
        cd $wpath
        echo "[$wpath]"
        n=0
        for i in `find ./ -type f | grep -e ${patterns/ / -e }`; do
            # Conv File Extension Upper Case to Lower
            # Linux Ver.
            #rename 's/\.([^.]*$)/.\L$1/' $i

            # Android Ver.
            fext="${i##*.}"
            if expr $fext : "[A-Z]" > /dev/null; then
                fext=`echo $fext | tr A-Z a-z`
                mv $i "${i%.*}" && mv "${i%.*}" "${i%.*}".$fext
            fi
            #echo $i "${i%.*}".$fext
        done
        for i in `find ./ -type f | grep -e ${patterns/ / -e }`; do
            # File Head Read
            # Android Cam: dp=2
            # Sony DSC   : dp=4
            # Xiaomi Cam : dp=6
            for dp in 2 4 6; do
                dt=`head -n $dp $i | grep -o '[0-9][0-9][0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]' --text`
                if [ -n "$dt" ]; then
                    break
                fi
            done

            # Touch File Timestamp
            if [ -n "$dt" ]; then
                dt=${dt//[: ]/}
                TZ=UTC-8 /data/busybox/busybox touch -t ${dt:0:12}.${dt:12:2} $i
                (( n++ ));
            else
                dt="NIL_NIL_NIL_NI"
            fi
            #echo $dt `stat -c "%y %n" ${i/'./'/} | sed -e 's/\.000000000//'`
            echo $dt `stat -c "%y %n" ${i/'./'/} | sed -e 's/\.[0-9]* / /g'`
        done
        echo "Total $n Files Corrected"
    else
        echo "[$wpath] Non Existent"
    fi
done

上記中のコメントにもありますが、自分が使う以下の機器が撮影する画像ファイルで動作確認をしています。

 

Image & Video Date Fixer アプリなら簡単

これらの自作スクリプトはrootedデバイスであるなどの制約がありましたが、今では同じことをしてくれる優れたアプリがいくつもあります。その中でもシンプルにして明快なのがこちらのImage and Video Date Fixerというアプリ。XDA Developersでも紹介されていて、概ね好評です。

Image and Video Date Fixer reads the EXIF metadata entries of images and videos to identify the original timestamp and sets it as the modification date. 
Image and Video Date Fixer restores the proper dates to your media files – xda-developers

Google Play で手に入れよう

インストールしてみると、アプリが必要とする権限は以下の通りで、その中で少し気になる、

「電話:デバイス情報とIDの読み取り」

は非許可としたままでも問題なく使うことができました。

図1.Image and Video Date Fixerアプリ

図1.Image and Video Date Fixerアプリ

アプリを立ち上げ、まずフォルダアイコンから対象フォルダを選択して、スキャンを実行。スキャン結果はプレビュー画面に一覧表示されるので確認の上、右下の「開始」をタップすると、「不適切な日付」に対して修正が加えられます。

図2.アプリ使用例

図2.アプリ使用例

この時無料版では、一度に修正することの出来るファイル数が50個までという制限がありますが、再実行すれば良いだけの話なのであまり意地悪な仕様にはなっていません。

 

メディアファイルのタイムスタンプ保持は、自分にとって優先度の高いライフテーマです。その分野で待ち望んだ秀悦なアプリとの出会いに、開発支援の意味でも課金してプレミアムバージョンにしてみるつもりです。

 

 

投稿 Androidで画像ファイル操作時に上書きされたタイムスタンプを復元Fun Scripting 2.0 に最初に表示されました。