素早く軽快なRetina対応のイメージにするサービス
前回、はてなフォトライフでも十分Retina対応のイメージを出力できると理解したが、一つだけ気がかりがある。それはひと月当たりのアップロード容量が30MBに制限されていること。このブログのスクリーンショットを撮影して、それぞれの画像サイズは以下のようになった。
画像 | ファイル | 30MB制限で アップロードできる枚数 |
---|---|---|
450px | 122KB | 245枚 |
900px | 388KB | 77枚 |
1280px | 682KB | 43枚 |
2758px(元画像) | 1400KB | 21枚 |
- 450pxと900pxでは、ファイル容量に3倍強の差がある。
- 30MB制限でアップロード可能な枚数を見ると、245枚から77枚になってしまう...。
- たいていの月は77枚で足りると思うが、記事の内容によってはそれ以上の容量が欲しいこともあるかもしれない。
- また、450pxに縛られる必要はないのだから、VGAサイズ(640px)でRetina対応しても良いのかもしれない。
- 1280pxの画像を用意しておいて、それをimgタグで640pxに縮小表示する。
- その方が、全画面のスクリーンショットでも細部の文字がつぶれずに判読可能なレベルになった。
- すると、さらにアップロード可能枚数は減って43枚。これではちょっと足りない気がする。
- それに、アップロード制限にはなんとか収まったとしても、1画像サイズは3倍強、5倍強の大きさになってしまう。
- ブラウザで表示した時の画像表示の重さが気になる。
画像のファイル容量をダイエットする必要がありそう!
PNG画像を圧縮する
調べてみると、素晴らしいツールが見つかった!
- ImageAlpha ― lossy compression for 24-bit PNG images (like JPEG with alpha channel!)
- ImageOptim ― make websites and apps load faster (Mac app)
- 2つのアプリケーションをダウンロードして、それぞれのファイルに適用してみる。すると...
-
-
- PNG画像をDockのImageAlphaアイコンにドラッグ&ドロップして、
-
-
-
- ↑デフォルト + 一応 IE6-frendly alpha にもチェックを入れてみた。
-
-
-
- ↑Save As...の時に、Optimize with ImageOptimにチェックを入れて保存することで、ImageOptimと連携できるのだ。
-
素晴らしい!すべて元ファイルの1/3以下になった。
画像 | ファイル | ImageAlpha& ImageOptim圧縮 |
30MB制限で アップロードできる枚数 |
---|---|---|---|
450px | 122KB | 39KB | 245枚 → 769枚 |
900px | 388KB | 115KB | 77枚 → 260枚 |
1280px | 682KB | 195KB | 43枚 → 153枚 |
2758px(元画像) | 1400KB | 366KB | 21枚 → 81枚 |
- 素晴らしい圧縮率。900pxは、PNG圧縮前の450pxよりも小さくなった!
- 圧縮前後の画質を確認してみた。(左:圧縮前 / 右:圧縮後)
- 画像が小さいこともあるが、ほとんど違いに気付かないレベル!
- 自分が利用するスクリーンショットにおいては、十分な品質だ!
- ちなみに、圧縮の仕組みは...
- ImageAlphaは、256色に減色しているようだ。
- ImageOptimは、何をやっているかよく分からない。(メタデータの削除?)
コマンドから使う
- GUIのアプリケーションは取っ付きやすいのだけど、ブログを素早く更新するルーチンワークとして使い始めると、一連の操作が一気に面倒くさくなる...。
- ところが、これらのアプリケーションはAppleScriptには対応していないのだが、コマンドラインから簡単に実行できることが分かった!
- pngquantについては、オプション設定によって画質の細かな調整も可能。以下のコマンドは一例。
$/Applications/ImageAlpha.app/Contents/Resources/pngquant -iebug -speed 3 -force -ext .png 256 ファイル名.png$ /Applications/ImageAlpha.app/Contents/Resources/pngquant --iebug --speed 3 --force --ext .png 256 ファイル名.png $ open -a ImageOptim.app ファイル名.png
サービスに仕上げる
- それぞれのAppleScriptとシェルコマンドの詳細は、以下のようなコードになっている。
--指定px以上の画像のみリサイズする
on run {input, parameters} (* input = {alias, alias, ...} *)
set output to {} set {num, act} to gets() repeat with an_alias in input
set output's end to resize(an_alias, num, act) end repeat
tell application "Finder" to delete input
return output
end run
on resize(an_alias, limit, act) set {fdir, fname, fext} to parse_file(an_alias) set resize_path to fdir & fname & "_" & limit & fext
tell application "Image Events"
launch
set myImage to open file (an_alias as text) set {w, h} to myImage's dimensions
if w > limit or h > limit then
if limit > 1 then
scale myImage to size limit
else if limit > 0 then
scale myImage by factor limit
end if
save myImage in file (resize_path) as PNG
close myImage
POSIX file resize_path as alias
end if
end tell
end resize
on gets() repeat
activate
"900 = 900pxにリサイズ
0.5 = 50%にリサイズ
空白 = リサイズしない"
display dialog result default answer "900" with icon 1
try
set res to result
set n to res's text returned as number
set B to res's button returned
exit repeat
end try
end repeat
{n, B} end gets
on parse_file(fpath) if fpath's class ≠ text then set fpath to (fpath as alias)'s POSIX path
{do shell script "ruby -e \"puts File.dirname(" & fpath's quoted form & ")+'/'\"", ¬ do shell script "ruby -e \"puts File.basename(" & fpath's quoted form & ", '.*')\"", ¬ do shell script "ruby -e \"puts File.extname(" & fpath's quoted form & ")\""} end parse_file
for f in "$@"; do echo "$f"; done /Applications/ImageAlpha.app/Contents/Resources/pngquant --iebug --speed 3 --force --ext .png 256 "$@" >/dev/null 2>&1; exit 0
for f in "$@"; do echo "$f"; done open -a ImageOptim.app "$@"
--完了のメッセージを通知
on run {input, parameters} (* input = {alias, alias, ...} *)
message(my name, "減色&メタ削除で最適化しました。" & return & join(fname_list(input), ", ")) return input
end run
on message(a_title, a_msg) try
"/usr/bin/terminal-notifier " & " -title " & quoted form of a_title & " -message " & quoted form of a_msg
do shell script result
on error
activate
display dialog a_title & return & a_msg buttons {"OK"} with icon 1 giving up after 5
end try
end message
on fname_list(alias_list) set a_list to {} repeat with an_alias in alias_list
set a_list's end to fname(an_alias as text) end repeat
a_list
end fname_list
on fname(f) try
tell application "Finder" to (f as alias)'s name
on error
tell application "Finder" to (f as POSIX file as alias)'s name
end try
end fname
on join(sourceList, delimiter) set oldDelimiters to my text item delimiters
set my text item delimiters to delimiter
set theText to sourceList as text
set my text item delimiters to oldDelimiters
theText
end join
インストール
- イメージを圧縮する.workflow.zipをクリックしてダウンロードし、解凍する。
- 二本指クリックして、イメージを圧縮する.workflowを開く。
- 「インストール」ボタンを押せば、インストールが完了する。
使い方
- FinderでPNG画像を二本指クリックすると、サービスメニューが表示される。
- 「イメージを圧縮する」を選択すれば、指定した画像サイズにリサイズしてから、ImageAlpha&ImageOptim圧縮が始まる。
- 圧縮後、元画像はゴミ箱に移動される。もし圧縮画像が気に入らなかったら、Finderでcommand-Zすると復活できる。
terminal-notifier
- イメージを圧縮する.workflowは、terminal-notifierを利用して、メッセージを通知する。
- terminal-notifierをインストルしておいた方が、より満足度の高いサービスとなるのだ。
第一階層のサービスメニューにする
- OSXデフォルトでは4つ以上サービスが登録されていると、二本指クリックのコンテクストメニューに「サービス」という項目が作成されて、2階層目にサービスが展開されてしまう。
- 自分にとってサービスメニューはよく使う操作なので、2階層目のメニューを選択するのは、マウスの軌跡を階段状に移動させなくてはならず、煩わしい...。
そこで...
# 99項目を超えるとサブメニューになる defaults write -g NSServicesMinimumItemCountForContextSubmenu -int 99 # 4項目を超えるとサブメニューになる(デフォルト) defaults delete -g NSServicesMinimumItemCountForContextSubmenu
これで、サービスメニュー1クリックでPNG画像がWebページに最適化されるようになった!
サービスにショートカットを設定しておけば、キー操作一発でも圧縮が始まる。快適である。