Subscribed unsubscribe Subscribe Subscribe

豪鬼メモ

一瞬千撃

Googleフォトに写真のバックアップを無制限かつ無劣化で置く方法

写真データのバックアップを、Googleフォト上に保存するための最適な方法を模索してみた。結論から言うと、TIFF画像をアップロードするとよい。

f:id:fridaynight:20160316182537j:plain


日常生活を記録した写真がハードディスク内に日々溜まっていくわけだが、ハードディスクは一定の確率で突然壊れるので、バックアップをとることは必須だ。ハードディスクを2台用意して同一データを2台ともに置くのもよいが、それでも同時に壊れる事例がたまにある。同じ環境に置いてあるなら機械の寿命は同期しがちだからだ。時間経過だけでなく衝撃、振動、湿度、温度などの日常的なストレスのほか、火災、水難、盗難、誤操作、子供の悪戯などもリスクになる。したがって、バックアップはクラウド環境に置くのが望ましい。クラウドクラウドでパスワード紛失やクラックや規約変更やサービス終了などのリスクがあるが、異なる種類のリスクであるため、ローカル環境とクラウド環境の両方にデータを分散することでデータ消失の可能性は非常に低くなる。

クラウド環境にデータを置くことの最大のデメリットはコストであるが、Googleフォトの無料メニューの拡充によってその問題はほぼ解決されたと言える。1円も払うことなく、データを無制限に置くことができるのだ。ネット上にデータがあるのでスマフォで見たり家族や友人にシェアしたりできるメリットは大きく、またAIによる自動分類や検索などの便利な機能も利用できる。こんなの素晴らしすぎて使わない理由が無い。

唯一の懸念点は、無料かつデータ量無制限の「高画質」モードだと、JPEGデータをアップロードするとデータが再圧縮されることである。これは非可逆圧縮なので、画質が劣化することになる。見た目ではほとんどわからない微妙な違いしか生じないが、劣化するとなると元データのバックアップとは言えなくなってしまう。また、自分は画像加工をよくするので、再加工に向かないJPEG形式で元データを保存するのは望ましくない。「オリジナル」モードだと15GBまでは無料だが、それ以上は有料でストレージ領域を購入する必要がある。1TBで月額10ドルという価格設定はかなりリーズナブルではあるが、一旦課金するとデータを保持する限り金を払い続けなければならないのが痛い。無料であればたとえ破産したり死んだりしてもデータが消されることはない。子供達の写真は結婚式の写真スライドを作るまでとっておかなくちゃね。

f:id:fridaynight:20090810145500j:plain

いろいろ試してみて気づいたのだが、GoogleフォトにTIFF画像をアップロードした場合、サーバ側では何ら加工が行われず、アップロードしたのと全く同じデータがダウンロードできる 。MD5で確認した。これなら完全なバックアップと言える。しかもアップしたデータはTIFFなのに表示用のJPEG画像も作られるので、全てのWebブラウザで画像を見られる。めちゃ便利だ。ちなみに各社のRAW形式もアップロードできるが、それはサーバ側でJPEGに変換されてしまうのでバックアップ用途には使えない。TIFFだけはなぜか優遇されていて、元データがそのままダウンロードできるのだ。16ビットTIFFにも対応しているので、再加工にも向いている。

ただし、アップロードできる画像には制限がある。1600万ピクセルを超える画像や、ファイルサイズが50MBを超える画像は、アップロードに失敗する。JPEGの場合は1600万ピクセルを超えると自動的に1600万ピクセルに縮小されるが、TIFFだとサーバ側で加工が行われないので、大きすぎる場合には単にエラーになる。この制限の中でいかに質の高い情報を保存するかが勝負になってくる。

まず最初に、自分が許容できる解像度を考えてみる。2016年現在の普及帯のディスプレイで写真を表示するとなると、フルHD(1920x1080)の解像度で十分ではあるが、近い将来に4K(3840x2160)の閲覧環境が整うと予想される。よって、この4K解像度を基準に考えてみる。3840 * 2160 = 8294400で、だいたい800万ピクセルとなり、1600万ピクセルの半分ということになる。非圧縮の16ビットTIFFだと各ピクセルは3チャンネルが2バイトずつ食うので、8294400 * 6 = 49766400で、だいたい47MBとなる。ぴったりじゃん。実際にはTIFF画像は内部データをZIP圧縮できるので、それを適用すると典型的には70%程度のサイズになるのだが、圧縮率は事前に予測できないので、最悪値を見積もっておく必要がある。よって4K解像度の16ビットTIFFというのは現状で最善の設定だと言えるだろう。

3840x2160は縦横16:9の比率だが、多くの写真は3:2や4:3の比率なので、それらにおいても800万ピクセル付近のキリのいい解像度を考えてみる。

  • 1:1 -- 2700 * 2700 = 7290000ピクセル
  • 4:3 -- 3200 * 2400 = 7680000ピクセル
  • 3:2 -- 3480 * 2320 = 8073600ピクセル
  • 16:9 -- 3840 * 2160 = 8294400ピクセル
  • 2:1 -- 4000 * 2000 = 8000000ピクセル
  • 3:1 -- 4800 * 1600 = 7680000ピクセル
  • 4:1 -- 5600 * 1400 = 7840000ピクセル
  • 5:1 -- 6000 * 1200 = 7200000ピクセル
  • 6:1 -- 6400 * 1066 = 6822400ピクセル

実際に写真ファイルを変換してバックアップ用ファイルを作るには、以下ようなコマンドを実行すればよい。この例では写真のサイズが4:3だとあらかじめわかっているものとして、長辺を3200ピクセルにするようにリサイズしている。

$ convert input_photo.jpg -auto-orient -resize 3200x3200 -depth 16 -strip backup_data.tif

実行すると約44MBのファイルが生成されることが確認できるだろう。さらに -compress zip というオプションをつけるとTIFFの内部データを圧縮するので、ファイルサイズは35MBとかになるだろう。単にTIFFに変換するだけだとEXIFデータが引き継がれないことがあるので、念の為に以下も実行しておいた方がよい。

$ exiftool -tagsFromFile input_photo.jpg -Orientation=1 -n -F -overwrite_original backup_data.tif

1600万ピクセルの8ビットTIFFでも確実に50MB以下になるので、JPEG圧縮を避けたいだけならばそれでもよい。その場合のキリのいい解像度も調べてみた。

  • 1:1 -- 3900 * 3900 = 15210000ピクセル
  • 4:3 -- 4608 * 3456 = 15925248ピクセル
  • 3:2 -- 4890 * 3260 = 15941400ピクセル
  • 16:9 -- 5312 * 2988 = 15872256ピクセル
  • 2:1 -- 5560 * 2780 = 15456800ピクセル
  • 3:1 -- 6780 * 2260 = 15322800ピクセル
  • 4:1 -- 7800 * 1950 = 15210000ピクセル
  • 5:1 -- 8700 * 1740 = 15138000ピクセル
  • 6:1 -- 9516 * 1586 = 15092376ピクセル

あるいは、ZIP圧縮した16ビットTIFFを作ってみて、そのサイズが50MBを超えなくなるまで少しずつ解像度を落としていくという作戦もいいかもしれない。究極的には閲覧性を完全に無視するならば画像を分割してアップロードする技によって無限に大きい画像を保存できる。ただ、現実的にはそんなに解像度だけを求めてもしょうがないだろう。カラー写真はベイヤー配列の画素補完をするので1600万画素のセンサーで撮ったら実質は800万ピクセル以下の情報しか持っていない。レンズの性能やピントの精度やローパスフィルタの影響でもデータが持っている実質的な情報量は頭打ちになる。

さて、既にハードディスク内にある大量の写真ファイルから一気に上述の設定のバックアップ用ファイルを生成するべく、スクリプトを書いてみた。MacLinuxで動くはずで、RubyImageMagickとExifToolが必要。このスクリプトは、ファイルサイズの見積もりが50MBより大きい場合にのみ解像度の変更をした上で、16ビットTIFFを指定したディレクトリに書き出すものだ。元の写真のアスペクトに合わせて画像サイズを適切に決めてくれるところがツボである。ついでに画像の正立やEXIFデータのコピーもやってくれる。

以下のように、ディレクトリを指定すると、そのディレクトリ以下の画像ファイル(JPEGTIFFPNGJPEG2000等)からバックアップ用の画像ファイルを作ってくれる。あとはそれをGoogleフォトのアップローダを使ってアップロードすればよい。

$ ./backupphoto image_dir -outdir backup_dir

標準入力からパスを読み込ませることもできるので、findコマンドと組み合わせると便利。

$ find image_dir -type -f -name '*-original.*' | ./backupphoto -stdin -outdir backup_dir

このスクリプトは動画ファイルにも対応しているが、動画ファイルは何の加工もせずにコピーするだけである。ちなみにGoogleフォトに動画をアップロードした場合、フルHD以上の解像度だとフルHDに落とされ、それ以下の解像度でも再圧縮がかかるらしい。なので元データのバックアップとしては位置付けられない。まあ動画に対する画質の要求は個人的には高くないし画像処理もしないのでよしとする。

Googleフォトにアップロードするにあたっては、Google Photo Backupというアプリケーションを使いたくなる。しかし、なぜかこいつはTIFFファイルを認識してくれない。したがってWebブラウザのアップロード機能を使うことになるのだが、ファイル選択ダイアログでシフトを押しながら始点と終点を選択すると多数のファイルを一括選択できるので、支障はない。

実際に100GBほど(写真25000ファイル80GBと動画600フィアル10GB)を5回に分けてアップロードしてみた。一括処理中に回線が切れたりした場合の復旧を考えると、5000ファイルくらいごとに小分けにして処理した方がいいような気がする。そうすると、回線速度にもよるが、寝る前に開始すると朝起きた時に終わってる感じになる。結果的には何の問題もなく処理されて、全てのデータを閲覧できるし、ダウンロードもできるようになった。Google Driveの残り容量も全く減っていない。こんなにすんなりいくのがむしろ意外だった。

ということで、Googleフォトは写真バックアップシステムとして活用できる。綺麗、便利、そして無料。最高だ。「思い出は何枚でも保存、見たいときはすぐ」というキャッチコピーに偽りはない。よく撮れた写真を選んでアルバムを作って家族や友達とシェアできるのはもちろん、何枚かの写真で組写真(コラージュ)やアニメGIFを作ってブログに貼るのも楽ちんだ。それらをAIが自動的に作ってくれるアシスタント機能も面白い。何より最も便利なのは、位置情報による検索である。「Hawaii」とか入れると一昨年に行ったハワイ旅行の写真に即座にアクセスできるのだ。
f:id:fridaynight:20140207120927j:plain

閲覧機能はGoogleフォトに任せるとすれば、自分で管理するファイルは現像後の16ビットTIFFだけにしてもいいかも。JPEGTIFFに変換してアップロードするのではなく、そもそも現像時にTIFFしか作らないということ。ローカルのハードディスクなんてバイト単価はめちゃ安いし、クラウド側は完全無料なのだから、非可逆圧縮で劣化したJPEGを元データとして保存する必要なんてもはやない。音楽データの保存方法がMP3からハイレゾ音源になったのと同じような変化が写真でも起きつつある。その流れで、カメラ内現像で16ビットTIFFを保存できる機種がそろそろ出てきてほしいなと強く思う。

最後に、繰り返しになるが、ローカル環境にもクラウド環境にも各々の利点(性能・操作性)と欠点(コスト・リスク)があるので、組み合わせて使った方がよい。自分は、米国で登録したFlickrアカウントにデータを突っ込んで運用していたのだが、日本帰国後にログインしようとしたら米国の電話番号にSMSを送って認証しないといけなくなって詰んだことがある。そんなアホなミスはしないと思うかもしれないが、事故は起こるものなのだ。