14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vim その2Advent Calendar 2018

Day 15

古い写真のアルバムをスマホで見るようにしたお話

Last updated at Posted at 2018-12-13

(この記事は「Vim2 Advent Calendar 2018」の15日目です)


IMG_9107.jpeg

Summary

これを ( 古い写真アルバム )

foo.png

こうした ( 家族のだれでも iPhone で写真を見れるようになった)

bar.PNG


ゴールとかとか

Motivation

引っ越すよ
写真アルバムはスペースとるよ
誰もみてないよ
捨てるのもアレだよね

Goal

場所をとらないようにする
気軽に見れるようにする

やってみようと思ったこと

写真をデーター化して Apple's iCloudShared albums ( see: Others 01. Apple's iCloud Shared albums ってなに? ) を利用して家族の誰でも気楽に写真を見れるようにする!


やったこと

01. 業者さんに写真データーのデジタル化を依頼    
02. 納品データーのチェック                      
03. 重複データーを除く                          
04. 時系列に並び替えてグルーピングする          
05. Apple Shared albums に写真をアップロードする

01 業者さんにデジタル化依頼

ここの作業、楽かと思ってたのですが意外とつらかったです・・・

01 アルバムをページごとにすべてデジカメで写真を撮る
02 アルバムから写真をべりべりはがす
03 アルバムごとの写真の枚数をエクセルに記入する
04 業者さんに発送

01-01 アルバムをページごとにすべてデジカメで写真を撮る

まず控えとして写真アルバムを記録します。写真の並びとか文字情報とかかなり重要なんで絶対に撮っておきます。(単調作業で途中で嫌になってきます)

03.jpg

01-02 アルバムから写真をべりべりはがす

依頼用にベリベリ剥がします。業者さんのコースによっては剥がさなくてもいいコースがあるのですが依頼料金が跳ね上がるので、お金のない callmekohei は頑張ってベリベリ剥がしましたよ。 写真を傷つけないようにかなり神経を使うので休み休みやるのがおすすめ。心を無にしてマシーンになりませう!

04.jpg

01-03 アルバムごとの写真の枚数をエクセルに記入する

剥がした写真の枚数をエクセルとかに簡単にメモしておきます

05.png

01-04 業者さんに発送

依頼書類とか制約事項誓約書とかを記入して、箱詰めとかして業者さんに送ります

この状態にするのも一苦労やで・・・

10.jpg


02 納品データーのチェック

ここはコーヒー片手にささっとできちゃいます

01 納品データーのファイル構成を確認
02 枚数のチェック
03 以前に控えたアルバムの写真とつきあわせ

02-01 納品データーのファイル構成を確認

callmekoheiDVD での納品形態を選んだので、外付けの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)

06.png

03-02 重複写真をのぞく(アプリを使用する)

Similar Photos Cleaner というアプリを使ってみたのですが、小一時間やってみたのですが、callmekohei的にはうまく使いこなせず、思うように重複写真をピックアップできなかったです。

かなり迷ったのですが、目視で行くことに決めました!

03-03 重複写真をのぞく(官能評価でおこなう)

目視で重複データーをチェックしました。

まず全ての写真のコンタクトシートを印刷します。コンタクトシートとは写真の一覧表です。左にSL,PFのコンタクトシート、右にBAのコンタクトシートを置いて、SL,PFの写真一枚毎にBAの写真全てに対して重複チェックします。重複写真が一枚の場合もあればそれ以上の場合もあるので最後までBAの写真を確認します

実際の作業様子

07.jpg

トランプの神経衰弱っていうゲームあるじゃないですか?あれの辛いバージョンな感じでしたよ。。。


04 時系列に並び替える、フォルダわけ

重複データーを消し込んだら次は時系列に写真をソートします。具体的にはまずソートする前に簡単なメモを作っておきます例えばこんな感じ

10.png

あとはアルバムに記載されてた文字情報、アルバムの並び、自分の記憶、人の記憶、背景・風景、人の外見等でソートします(具体的にはPhots.appImage > Adjust Date and Time... > Adjusted にて日時を調整してソートします)。それと割と新し目の写真には右下に日時が印字されてるのですが、間違ってることも多々あるので、おかしいなと思ったら盲目的に信じずに確認しました。

ここまでできたら、あとは写真をグループ分けするだけです!(僕の場合は引越しが多かったので居住地で分けました)

あとアルバムが結構いい加減で違う時間軸が混じってたりしたのですが、背景は意外と情報を与えてくれて整理するのに役立ちました。例えば下記の写真は、同じアルバムに入ってて並んでたのですが、実は違う住居地だったのが襖の模様でわかるという感じです

08.png


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.appImage > 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.jpgexifデーターが変更されているのが確認できました

さて今回やりたいことはphoto.appでの表示順どおりにshared albumsにも表示したいということです。別の言い方をすると、photos.appではソートキーが第一キーが日時、第二キーがファイル名になっているのが観察されます。この並び順を時刻でするにはどうすればいいかは下記になりそうです

1. 1stソートキーを日時、2ndソートキーをファイル名にしてソートする
2. 時刻をリセット(`00:00:00`)にする
3. ソートした順に1秒ずつ足していく

やりたいことをするための手順はわかったのであとはExiftoolでどのようにするかを調べれば良さそうです。グーグル検索で調べてみました

しかしcallmekoheiのググる力がアレなためうまく見つけることができません

そういえばヘルプあるじゃんと・・・

$ exiftool --help

11.png

ヘルプは出てきたのですが、lessという文書閲覧プログラムをよく知らないためうまく読むことができません

05-03 vimでヘルプを読む

そういえばVimでもヘルプを読むことができるのを思い出しましたよ ( see: Others 03. vim の Man コマンドの設定)

# Vimを立ち上げて
$ vim
" Manコマンドで読みたいコマンド名を指定する
: Man exiftool

色がついてる!

12.png

折りたたみも自由自在!

13.png

もちろん検索も簡単です!

14.png

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 に意図した順番で登録できました!



おしまい。。。



(読んでくれてありがとうございますねっ)

baz.jpeg





Others

01. Apple's iCloud Shared albums ってなに?

Appleのホームページによれば下記とのこと

共有アルバムを使えば、
自分で選んだ家族や友人とだけ写真やビデオを共有でき、
相手にも写真、ビデオ、コメントを投稿してもらえます。

---> 写真 App で共有アルバムを使う
---> マイフォトストリームと共有アルバムの制限

// (注)callmekohei のイメージです
アップルが写真データーの保存用に貸してくれるサーバーのこと
iCloudサーバーに保存した写真データーのみ shared albums 用のサーバーにコピーすることができる

こんな感じ( メモ書き )

02.jpg


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 でヘルプを調べる

IMG_9298.jpeg

: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倍速〜)

14
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?