(この記事は「Vim2 Advent Calendar 2018」の15日目です)
Summary
これを ( 古い写真アルバム )
こうした ( 家族のだれでも iPhone で写真を見れるようになった)
ゴールとかとか
Motivation
引っ越すよ
写真アルバムはスペースとるよ
誰もみてないよ
捨てるのもアレだよね
Goal
場所をとらないようにする
気軽に見れるようにする
やってみようと思ったこと
写真をデーター化して Apple's iCloud
の Shared albums
( see: Others 01. Apple's iCloud Shared albums ってなに? ) を利用して家族の誰でも気楽に写真を見れるようにする!
やったこと
01. 業者さんに写真データーのデジタル化を依頼
02. 納品データーのチェック
03. 重複データーを除く
04. 時系列に並び替えてグルーピングする
05. Apple Shared albums に写真をアップロードする
01 業者さんにデジタル化依頼
ここの作業、楽かと思ってたのですが意外とつらかったです・・・
01 アルバムをページごとにすべてデジカメで写真を撮る
02 アルバムから写真をべりべりはがす
03 アルバムごとの写真の枚数をエクセルに記入する
04 業者さんに発送
01-01 アルバムをページごとにすべてデジカメで写真を撮る
まず控えとして写真アルバムを記録します。写真の並びとか文字情報とかかなり重要なんで絶対に撮っておきます。(単調作業で途中で嫌になってきます)
01-02 アルバムから写真をべりべりはがす
依頼用にベリベリ剥がします。業者さんのコースによっては剥がさなくてもいいコースがあるのですが依頼料金が跳ね上がるので、お金のない callmekohei
は頑張ってベリベリ剥がしましたよ。 写真を傷つけないようにかなり神経を使うので休み休みやるのがおすすめ。心を無にしてマシーンになりませう!
01-03 アルバムごとの写真の枚数をエクセルに記入する
剥がした写真の枚数をエクセルとかに簡単にメモしておきます
01-04 業者さんに発送
依頼書類とか制約事項誓約書とかを記入して、箱詰めとかして業者さんに送ります
この状態にするのも一苦労やで・・・
02 納品データーのチェック
ここはコーヒー片手にささっとできちゃいます
01 納品データーのファイル構成を確認
02 枚数のチェック
03 以前に控えたアルバムの写真とつきあわせ
02-01 納品データーのファイル構成を確認
callmekohei
は DVD
での納品形態を選んだので、外付けのHDD
に一旦コピーします。(作業をしやすくするため)
こんな感じのファイル構成でした
納品データー/
├── DVD1
│ ├── _インデックス
│ └── バラ写真
│ ├── BA001
│ | ├── 色補正前データー
│ | | ├── BA001_0001.jpg
│ | | ├── BA001_0002.jpg
│ | | └── ...
│ | └── 色補正後データー
│ | ├── BA001_0001.jpg
│ | ├── BA001_0002.jpg
│ | └── ...
│ └── BA010
├── DVD2
│ ├── _インデックス
│ └── バラ写真
│ ├── BA011
│ ├── ...
│ └── BA029
├── DVD3
│ ├── _インデックス
│ └── フィルム
│ ├── SL001
│ | ├── 色補正前データー
│ | | ├── SL001_0001.JPG
│ | | ├── SL001_0002.JPG
│ | | └── ...
│ | └── 色補正後データー
│ | ├── SL001_0001.JPG
│ | ├── SL001_0002.JPG
│ | └── ...
│ └── SL050
└── DVD4
├── _インデックス
├── フィルム
│ ├── SL051
│ ├── ...
│ └── SL090
└── ポケットフィルム
├── PF001
| ├── 色補正前データー
| | ├── PF001_0001.JPG
| | ├── PF001_0002.JPG
| | └── ...
| └── 色補正後データー
| ├── PF001_0001.JPG
| ├── PF001_0002.JPG
| └── ...
├── ...
└── PF005
02-02 枚数のチェック
下記のコマンドでフォルダ毎に写真データーの枚数を出して、前にエクセルに記入した写真の枚数と照合します
#!/usr/bin/env bash
function foo () {
local folder=$1
local path=${HOME}/Desktop/albums/${folder}
for d in $(find $path -type d)
do
local cnt=$( ls "$d" | grep -e 'jpg' -e 'JPG' | wc -l )
if [ ! $cnt == "0" ] ; then
echo $d" ---> "$cnt \
| grep -e 'BA' -e 'SL' -e 'PF' \
| sed -e 's|'${HOME}'/Desktop/albums||g'
fi
done
}
foo DVD1 | sort
foo DVD2 | sort
foo DVD3 | sort
foo DVD4 | sort
結果
/DVD1/バラ写真/BA001/色補正前のデータ ---> 53
/DVD1/バラ写真/BA001/色補正後のデータ ---> 53
/DVD1/バラ写真/BA002/色補正前のデータ ---> 86
...
02-03 以前に控えたアルバムの写真とつきあわせ
枚数はオーケーだったので、内容を目視でチェックします。ここはまぁだいたいで。
02-04 フォルダ構成を変更する
扱いやすいようにファルダ構成を変えます
色補正後データーに特に問題がなかったのでその分のデーターをまとめて下記のようにします
作業途中でよくわからない状態になって、下記の状態から作業を始めることが頻繁に起きたので下記の状態にするスクリプトをF#
で書きました ( see: Others 02. F#でフォルダコピー )
納品データー/
├── BA
| ├── BA001
| ├── BA001_0001.JPG
├── SL
| ├── SL001
| ├── SL001_0001.JPG
└── PF
├── PF001
├── PF001_0001.JPG
03 重複データーのチェック
ここが一番辛かったです・・・。コードを書いて解決できればよかったのですが僕にはそのスキルがなかったです
01 衝(main)となる写真種別を決める
02 重複写真をのぞく(アプリを使用する)
03 重複写真をのぞく(官能評価でおこなう)
03-01 衝(main)となる写真種別を決める
写真種別は今回3種類ありました
写真種別 | 意味 | callmekoheiの感想 |
---|---|---|
SL | フィルムからのデーター | 結構クリア |
PF | フィルムからのデーター | 結構クリア |
BA | 現像プリント写真からのデーター | 野暮ったい感じ |
SL,PF
にしかない写真もあれば、BA
にしかない写真もありますが、大部分はSL,PF
にもあってかつBA
にあるという状況でした。
何点か見比べてSL,PF
を衝としました。もしかしたらBA
のほうが綺麗な(味のある)写真があるかもですがそこはもう機械的にばっさりいきます
SLとBAのデーターの比較(左がSL, 右がBA)
03-02 重複写真をのぞく(アプリを使用する)
Similar Photos Cleaner というアプリを使ってみたのですが、小一時間やってみたのですが、callmekohei
的にはうまく使いこなせず、思うように重複写真をピックアップできなかったです。
かなり迷ったのですが、目視で行くことに決めました!
03-03 重複写真をのぞく(官能評価でおこなう)
目視で重複データーをチェックしました。
まず全ての写真のコンタクトシートを印刷します。コンタクトシートとは写真の一覧表です。左にSL,PF
のコンタクトシート、右にBA
のコンタクトシートを置いて、SL,PF
の写真一枚毎にBA
の写真全てに対して重複チェックします。重複写真が一枚の場合もあればそれ以上の場合もあるので最後までBA
の写真を確認します
実際の作業様子
トランプの神経衰弱っていうゲームあるじゃないですか?あれの辛いバージョンな感じでしたよ。。。
04 時系列に並び替える、フォルダわけ
重複データーを消し込んだら次は時系列に写真をソートします。具体的にはまずソートする前に簡単なメモを作っておきます例えばこんな感じ
あとはアルバムに記載されてた文字情報、アルバムの並び、自分の記憶、人の記憶、背景・風景、人の外見等でソートします(具体的にはPhots.app
のImage > Adjust Date and Time... > Adjusted
にて日時を調整してソートします)。それと割と新し目の写真には右下に日時が印字されてるのですが、間違ってることも多々あるので、おかしいなと思ったら盲目的に信じずに確認しました。
ここまでできたら、あとは写真をグループ分けするだけです!(僕の場合は引越しが多かったので居住地で分けました)
あとアルバムが結構いい加減で違う時間軸が混じってたりしたのですが、背景は意外と情報を与えてくれて整理するのに役立ちました。例えば下記の写真は、同じアルバムに入ってて並んでたのですが、実は違う住居地だったのが襖の模様でわかるという感じです
05 Apple Shared albums に写真をアップロードする
Apple Shared albums
に追加するのは簡単です。下記の手順で簡単に追加することができます
Shared albums に送りたい写真を選択
> 右クリック
> Shared
> Shared Albums
ここで問題が発生しました
05-01 Shared albums に追加する際の問題
同一日時の写真はランダムに追加される
例えば下記3つのファイルはShared albums
に追加する場合、foo01 -> foo03 -> foo02
という並びになってほしいのですが、実際は foo01 -> foo03 -> foo02
もしくは foo03 -> foo01 -> foo02
となります。どちらになるかはその時次第という感じです
foo01.jpg 1983:01:01 12:11:42
foo02.jpg 1983:10:10 12:11:42
foo03.jpg 1983:01:01 12:11:42
追加順を確実にしたい場合は時刻を変更することでできます。たとえば上記のファイルの場合下記のようにすると確実に並び順を確定できます
foo01.jpg 1983:01:01 00:00:01
foo02.jpg 1983:10:10 00:00:03
foo03.jpg 1983:01:01 00:00:02
時刻を変更する場所は Phots.app
のImage > Adjust Date and Time... > Adjusted
にて変更可能です。ただ全ての写真データーに対してこの操作をするのは辛い感じがしたので、ネットで色々調べたところExifTool
というので変更できそうだということがわかりました!
05-02 ExifToolを使ってみる
グーグル検索してみるといろいろなホームページにexiftool
の使い方が載っているのでまずは試してみます
インストール
$ brew install exiftool
日付を変える
// 現状確認
$ exiftool -alldates foo.jpg
Date/Time Original : 1987:03:22 00:00:00
Create Date : 1987:03:22 16:14:50
Modify Date : 1987:03:22 16:14:50
// 日時を変更
$ exiftool -alldates="2999/01/01 00:00:01" foo.jpg
1 image files updated
// 変更されているか確認
$ exiftool -alldates foo.jpg
Date/Time Original : 2999:01:01 00:00:01
Create Date : 2999:01:01 00:00:01
Modify Date : 2999:01:01 00:00:01
foo.jpg
のexif
データーが変更されているのが確認できました
さて今回やりたいことはphoto.app
での表示順どおりにshared albums
にも表示したいということです。別の言い方をすると、photos.app
ではソートキーが第一キーが日時、第二キーがファイル名になっているのが観察されます。この並び順を時刻でするにはどうすればいいかは下記になりそうです
1. 1stソートキーを日時、2ndソートキーをファイル名にしてソートする
2. 時刻をリセット(`00:00:00`)にする
3. ソートした順に1秒ずつ足していく
やりたいことをするための手順はわかったのであとはExiftool
でどのようにするかを調べれば良さそうです。グーグル検索で調べてみました
しかしcallmekohei
のググる力がアレなためうまく見つけることができません
そういえばヘルプあるじゃんと・・・
$ exiftool --help
ヘルプは出てきたのですが、less
という文書閲覧プログラムをよく知らないためうまく読むことができません
05-03 vimでヘルプを読む
そういえばVim
でもヘルプを読むことができるのを思い出しましたよ ( see: Others 03. vim の Man コマンドの設定)
# Vimを立ち上げて
$ vim
" Manコマンドで読みたいコマンド名を指定する
: Man exiftool
色がついてる!
折りたたみも自由自在!
もちろん検索も簡単です!
05-04 Vimでヘルプを読む2
さてvim
を使ってヘルプを読めるようになりましたが、どのように調べればいいのでしょうか?callmekohei
がわからないことは
1. 1stソートキーを日時、2ndソートキーをファイル名にしてソートする
2. 時刻をリセット(00:00:00)にする
3. ソートした順に1秒ずつ足していく
の方法です。ここでは1
についての調べ方です。callmekohei
はこんな感じで調べました
まずは、ページ上部をパッと見ます。ふむふむ。
exiftool は options, tag and file と3つの種類の引数をとるんだな
SYNOPSIS
Reading
exiftool [OPTIONS] [-TAG...] [--TAG...] FILE...
ソートだからsort
で調べてみよっと /\vsort
-sort Sort output alphabetically
-sort, --sort
Sort output by tag description, or by tag name if the -s option is
used. When sorting by description, the sort order will depend on
ほむほむ。tag
でソートされますよ、と
さらにn
をおすと下記の文言が
-fileOrder [-]TAG
Set file processing order according to the sorted value of the
specified TAG. For example, to process files in order of date:
exiftool -fileOrder DateTimeOriginal DIR
Additional -fileOrder options may be added for secondary sort
keys. Numbers are sorted numerically, and all other values are
sorted alphabetically. The sort order may be reversed by
prefixing the tag name with a "-" (eg. "-fileOrder -createdate").
Print conversion of the sorted values is disabled with the -n
option, or a "#" appended to the tag name. Other formatting
options (eg. -d) have no effect on the sorted values. Note that
the -fileOrder option has a large performance impact since it
involves an additional processing pass of each file.
callmekohei
は英語苦手なのですが、多分
TAGでソートするよ
追加で -fileOrder 書いたら入れ子のソート(2nd sort)になるかもね
と書いてるので、こんな感じで書けるのがわかります!
$ exiftool \
-filename \
-fileorder datetimeoriginal \
-fileorder filename
vim
を使うとこのように自分の調べたいことに集中できるのでヘルプをちゃんと読むことができます!
05-05 BashScriptで連番振りスクリプト書いてみた
かなり四苦八苦しながらBashScript
で書いてみました!
function sortedFilepathList () { #{{{
# (その1)ソートされたファイルパスのリストを作成
# ExifToolのparamを配列に書く
declare -a arrFileOrder=(
-quiet
-fast2
-s3
-filename
-fileorder datetimeoriginal
-fileorder filename
)
# Date/Time Originalの日時でソートされたファイルパスのリストを変数にいれる
echo $( echo *jpg | xargs exiftool "${arrFileOrder[@]}" )
} #}}}
function resetAllTime () { #{{{
# (その2)時刻をリセットする
# ExifToolのparamを配列に書く
declare -a arrReset=(
-quiet
-fast2
-s3
-d '%Y:%m:%d 00:00:00'
-overwrite_original_in_place
"-DateTimeOriginal<DateTimeOriginal"
)
# Date/Time Originalの時刻をゼロにリセットする
echo *jpg | xargs exiftool "${arrReset[@]}"
} #}}}
function addOneSecond () { #{{{
# (その3)時刻を1秒ずつ進める
local baseStr="-quiet -fast2 -s3 -overwrite_original_in_place -DateTimeOriginal+=0:0:"
declare -a local arrFPList=( $fpList )
local len=$(( "${#arrFPList[@]}" - 1 ))
for idx in $( seq 0 $len ) ; do
local fileName="${arrFPList[(($idx))]}"
local orderedNumber=$idx
exiftool $fileName $baseStr$idx
done
} #}}}
function mainImpl () { #{{{
# 写真のあるフォルダに移動
local fld=$1
cd $fld
# (その1)ソートされたファイルパスのリストを作成
local fpList=$( sortedFilepathList )
# (その2)時刻をリセットする
resetAllTime
# (その3)時刻を1秒ずつ進める
addOneSecond
} #}}}
function main () { #{{{
# フォルダを指定する
local fld=$HOME/Desktop/tmptmp
export -f sortedFilepathList
export -f resetAllTime
export -f addOneSecond
export -f mainImpl
find $fld -type d | xargs -I % bash -c "mainImpl %"
} #}}}
main
結果
$ time bash foo.bash
real 9m2.675s
user 7m19.833s
sys 1m14.571s
これで無事 Apple Shared albums
に意図した順番で登録できました!
おしまい。。。
(読んでくれてありがとうございますねっ)
Others
01. Apple's iCloud Shared albums ってなに?
Appleのホームページによれば下記とのこと
共有アルバムを使えば、
自分で選んだ家族や友人とだけ写真やビデオを共有でき、
相手にも写真、ビデオ、コメントを投稿してもらえます。
---> 写真 App で共有アルバムを使う
---> マイフォトストリームと共有アルバムの制限
// (注)callmekohei のイメージです
アップルが写真データーの保存用に貸してくれるサーバーのこと
iCloudサーバーに保存した写真データーのみ shared albums 用のサーバーにコピーすることができる
こんな感じ( メモ書き )
02. F#でフォルダコピー
02-04 フォルダ構成を変更する
にて何度か元データーから上記のファイル構成を作成する必要があったのでF#
でコードを書いてみました
open System.IO
open System.Text.RegularExpressions
let SrcHDD_ = "/Users/callmekohei/Desktop/albums"
let DstHDD_ = "/Users/callmekohei/tmp4"
// コピーしたい写真データーのリストを作成する
let srcJPGs () =
["DVD1";"DVD2";"DVD3";"DVD4"]
|> List.map ( fun s ->
Directory.GetFiles( SrcHDD_ + "/" + s ,"*", SearchOption.AllDirectories)
|> Array.filter ( fun (s:string) -> s.Contains("色補正後のデータ") )
)
// コピー元のファイルパスとコピー先のファイルパスを組み(タプル)にしたリストを作成する
let dstJPGs () =
srcJPGs ()
|> List.map( fun arr ->
arr
|> Array.map( fun srcPath ->
let destinateFilePath =
Regex.Replace( srcPath, @"色補正後のデータ/" , "" )
|> fun s -> Regex.Replace( s, SrcHDD_ + @"/DVD\d/バラ写真" , DstHDD_ + "/BA" )
|> fun s -> Regex.Replace( s, SrcHDD_ + @"/DVD\d/フイルム" , DstHDD_ + "/SL" )
|> fun s -> Regex.Replace( s, SrcHDD_ + @"/DVD\d/ポケットフイルム" , DstHDD_ + "/PF" )
|> fun s -> Regex.Replace( s, ".JPG", ".jpg" )
srcPath, destinateFilePath
)
)
// もしコピー先のフォルダがなければ作成する
let createFolderIfnotExists () =
dstJPGs ()
|> List.map ( fun arr ->
arr
|> Array.map( fun tpl -> System.IO.Path.GetDirectoryName( tpl |> snd ) )
|> Array.distinct )
|> List.iter( fun arr ->
arr
|> Array.iter( fun folderPath ->
if not ( Directory.Exists( folderPath ) ) then
Directory.CreateDirectory( folderPath ) |> ignore
)
)
let main () =
createFolderIfnotExists ()
dstJPGs ()
|> Array.concat
|> Array.map ( fun (src,dst) -> async{ File.Copy(src, dst) } )
|> Async.Parallel
|> Async.RunSynchronously
main ()
実行はこんな感じ
$ time fsharpi foo.fsx
real 0m39.002s
user 0m5.849s
sys 0m54.564s
03. vim の Man コマンドの設定
Vim
の場合
" see ---> :h man.vim
" vimrcに書く
let runtime ftplugin/man.vim
" foldingを使いたい場合は記述
let g:ft_man_folding_enable = 1
Neovim
の場合
" 特に設定は必要なし
" see ---> :h nvim-features > Commands: > :Man
" vimrcに書く
" foldingを使いたい場合は記述
set foldmethod=indent
04. vim-ref でヘルプを調べる
:Man exiftool
とコマンドを調べましたが、例えばpython
のヘルプとかも同じような考え方で:pydoc print
とかでできないでしょうか?
vim-ref
というプラグインを使うとそういったことができます。
使い方はこんな感じ
exiftoolコマンドを調べる
# foo.bash
:Ref man exiftool
or
# exiftoolという単語の上で K を押す
exiftool
print関数を調べる
# foo.py
:Ref pydoc print
or
# printという単語の上で K を押す
print('foo')
install
vim-ref
をダウンロードする
$ git clone https://github.com/thinca/vim-ref
vim-ref
へのパスをセットする
" vimrc
set runtimepath+=/path/to/vim-ref
setting
こんな感じ
" see also :h ref.vim , :h ref-man , :h ref-pydoc
let g:ref_man_cmd = 'man'
let g:ref_pydoc_cmd = 'python3 -m pydoc'
注意ポイント
現象: 補完が効かない時がある
:Ref man exif "ここでタブ
"↓
:Ref man exif " 補完が効かない
原因: コマンド名がcache
されていない
1. man のコマンド名のキャッシュをつくる
:Ref man less
2. あらたにコマンドをついかする( $ brew install exiftool )
$ brew install exiftool
3. キャッシュファイルに exiftoolのコマンド名がないので補完されない
:Ref man exif...
対策: 下記のコマンドを実行する
:Ref -nocache man exiftool
or
:Ref -updatecache man
:Ref man exiftool
05. BashScriptのコードをElixirで書き直した話
BashScriptのコードを
Elixirで書き直したら
2倍近くはやくなりましたよ!
まずはElixer
のいろはをざっと学んで
F#を横目にElixirで「こんにちは世界」
で、コードを書いてみる・・・
BashScript を Elixir で書き直してみたっ(2倍速〜)