Exif情報を元にJPEGファイル名をリネームするJavaScript for Automation(2016年バージョン)

2014年に書いたこれ

を直した。

JPEGのファイル名を、Exif情報を元にリネームするスクリプト

iPhoneやデジカメで撮った写真のファイル名が、

img_20141024_012345_Apple_iPhone6_1.jpg

こんな感じになるスクリプト

「img + 年月日 + 時分秒 + カメラメーカー名 + カメラ名 + 連番 + .jpg」っていうルールでリネームする。連番は、カメラで連写などして年月日時分秒まで一致した場合にカウントアップする。

複数のカメラで撮った写真をひとつのフォルダにまとめて保存し、さらにレタッチしてファイルのタイムスタンプが変化してる場合などに、こういう風にファイル名がついていれば整理しやすい。

Exif情報を元にJPEGファイル名をリネームするJavaScript for Automation - 今日覚えたこと

当時の説明がこんな感じ。

コード

ソースコードは以下。

function openDocuments(docs) {
    var app = Application.currentApplication();
    app.includeStandardAdditions = true;
    
    var count = 0;
    for(var i = 0; i < docs.length; i++){
        var src = docs[i].toString();
        if(!/\.jpe?g$/i.test(src)) continue;
        
        // Get Exif
        var sips = app.doShellScript('sips -g all "' + src + '"');
        var lines = sips.split(/\r\n|\r|\n/).slice(1);
        var exif = {};
        for(var j = 0; j < lines.length; j++){
            /^\s*([^:]+): (.+)$/.test(lines[j]);
            exif[RegExp.$1] = RegExp.$2;
        }
        
        if(!exif.creation){
            // Get FileInfo
            var fileInfo = app.doShellScript('GetFileInfo "' + src + '" | grep created');
            exif.creation = fileInfo.replace(/^.+?([0-9]+)\/([0-9]+)\/([0-9]+) ([0-9:]+)/, '$3:$1:$2 $4');
        }
        if(!exif.make) exif.make = 'unknown';
        if(!exif.model) exif.model = 'unknown';
        
        // Generate Name
        var parent = src.replace(/[^\/]+$/, '');
        var dst;
        var index = 1;
        while(true){
            dst =
                parent +
                'img_' +
                exif.creation.replace(/:/g, '').replace(/ /, '_') + '_' +
                exif.make.replace(/[^a-z0-9-]/ig, '') + '_' +
                exif.model.replace(/[^a-z0-9-]/ig, '') + '_' +
                index.toString() +
                '.jpg';
            var ret = app.doShellScript('if test -e "' + dst + '"; then echo 1; else echo 0; fi');
            if(ret == '0') break;
            index++;
        }
        
        // Rename
        app.doShellScript('mv "' + src + '" "' + dst + '"');

        // Live Photos
        var lp_src = src.replace(/\.JPG$/i, '.MOV');
        var ret = app.doShellScript('if test -e "' + lp_src + '"; then echo 1; else echo 0; fi');
        if(ret == '1'){
            var lp_dst = dst.replace(/\.jpg$/i, '.mov');
            app.doShellScript('mv "' + lp_src + '" "' + lp_dst + '"');
        }

        count++;
    }
    
    app.displayAlert(count.toString() + ' file' + (2 <= count ? 's' : '') + ' renamed.');
}

macOS Sierraで動作確認した。特にOSの新機能とかを使ってるわけではないと思うので、JavaScript for Automationに対応しているYosemite以降なら動くと思う。

スクリプトエディタに上記のコードをコピペして、好きな場所にアプリケーション形式(.app)で保存する。

あとはそのappファイルに対してJPEGファイルをドラッグ&ドロップするとリネームされる。複数のファイルをドロップしてもOK。

2014年バージョンからの変更点

  • Exifに日付がない場合、代わりにファイルのタイムスタンプの日付を使うようにした
  • Exifにカメラメーカーやカメラ名が無い場合、エラーにならないでunknownとして動作するようにした
  • Live Photosに対応した。JPGと同じファイル名のMOVが存在している場合、MOVも同じようにリネームするようにした。

こんなところ。具体的には、SNOWで撮った写真にExifが入らないようなので、それでいちいちエラーにならないようにしたのと、iPhone 6s以降の新機能のLive Photosに対応した感じ。

まあ2年前には想定してなかった状況に対応したってこと。今後もまた何かあったら直すね。