feed
2015年05月05日, 編集履歴
「QuickTime PlayerでスクリーンキャプチャしたMOVからベターなアニメーションGIFを作る」で書いた方法よりも、より良い手法が解ったので覚え書き。
前回の手法をかんたんにまとめると、
- ffmpegを使って動画を連番画像に切り出す
- ImageMagickのconvertコマンドで連番画像をアニメーションGIFに纏める
だった。前回の手法の問題点は、手順2で処理に時間が掛かること、動画の内容によっては色味が変化、あるいは崩れる可能性があることだった。
今回の手法はImageMagickは用いずffmpegだけを用いる。ffmpegはv2.6以上必須。動画はffmpegが扱えるならなんでも良いと思う。
手順:
- ffmpegで動画で使われている色を元に最適化されたパレット画像を生成
- ffmpegでパレットを元にアニメーションGIFを生成
パレット画像の生成
パレット画像を生成するには、以下を実行する。
$ ffmpeg -i input.mov -vf palettegen -y palette.png
-i input.mov
で入力動画の指定、-y palette.png
で出力するパレット画像の指定。-vf palettegen
でパレット画像の生成を指定(palettegenフィルタのドキュメント)。
アニメーションGIFの生成
パレット画像を元にアニメーションGIFを生成するには、以下を実行する。
$ ffmpeg -i input.mov -i palette.png -lavfi paletteuse -y output.gif
入力動画と共にパレット画像も指定し、アニメーションGIFを生成する。-lavfi paletteuse
でパレット画像の使用を指定(paletteuseフィルタのドキュメント)。
結果
- 入力動画
- ImageMagickを用いた手法で生成したアニメーションGIF(前回の手法)
- パレット画像を使用せずにffmpegで生成したアニメーションGIF
- パレット画像を使用してffmpegで生成したアニメーションGIF(今回の手法)
を以下に示す。
| ファイルサイズ | 動画・画像 | 処理時間 |
入力動画 | 148KB | | |
ImageMagick(前回の手法) | 709KB |  | 約23秒 |
ffmpeg、パレット画像不使用 | 293KB |  | 約2秒 |
ffmpeg、パレット画像使用(今回の手法) | 663KB |  | 約6秒 |
ImageMagickを用いる手法(前回の手法)では、
$ ffmpeg -i input.mov -r 20 frames/%03d.png
$ convert -delay 5 -layers optimize frames/*.png output-imagemagick.gif
パレット画像不使用の手法では、
$ ffmpeg -i input.mov -r 20 -y output-ffmpeg-normal.gif
パレット画像使用の手法(今回の手法)では、
$ ffmpeg -i input.mov -vf fps=20,palettegen=stats_mode=diff -y palette.png
$ ffmpeg -i input.mov -i palette.png -lavfi fps=20,paletteuse -y output-ffmpeg-palette.gif
を実行した。
前回の手法で生成したアニメーションGIFはテキストエディタのウィンドウの背景が薄青く変色してしまっているのが解る。これはまだましな方で、動画によってはもっと大きく色が崩れてしまったり、前フレームの残像が残ったりすることがある。パレット画像不使用の場合はドロップシャドウやメニューなど、半透明がからむ部分で編みかけのようになってしまっている。それらに比べて今回の手法で生成したものは、そういう画像の乱れが見られない。
また、処理にかかった時間もパレット画像不使用に比べれば遅いものの、前回の手法の方よりは大幅に速い。出力ファイルサイズもパレット画像不使用よりは大きいが前回の手法よりは小さい、という結果になった。
おまけ(動画の切り抜き、拡大・縮小、FPSの変更)
QuickTime Playerでスクリーンキャプチャする際、範囲選択の領域サイズが表示されないので、狙った領域サイズで収録するのが難しい。そこで、範囲選択を大きめに取って収録し、ffmpegを用いて切り抜き、縮小する方法を考える。
切り抜きの場合、
$ ffmpeg -i input.mov -vf crop=640:480:52:0 -y output.mov
のようにする。-vf crop=640:480:52:0
で切り抜きを指定(cropフィルタのドキュメント)。この指定の場合、元動画の左上を原点として(52, 0)の座標から領域サイズ640x480での切り抜きを行う。
拡大・縮小の場合、
$ ffmpeg -i input.mov -vf scale=400:-1:flags=lanczos -y output.mov
のようにする。-vf scale=400:-1:flags=lanczos
で拡大・縮小を指定(scaleフィルタのドキュメント)。
FPSの変更は、
$ ffmpeg -i input.mov -vf fps=20 -y output.mov
のようにする(fpsフィルタのドキュメント)。
切り抜きしつつ、縮小しつつ、FPSを指定して、パレット画像の生成をするには、
$ ffmpeg -i input.mov -vf crop=640:480:52:0,fps=20,scale=400:-1:flags=lanczos,palettegen -y palette.png
さらに、このパレット画像を使用してアニメーションGIFを生成するには、
$ ffmpeg -i input.mov -i palette.png -lavfi crop=640:480:52:0,fps=20,scale=400:-1:flags=lanczos,paletteuse -y output.gif
を実行する。
ffmpegは引数指定が複雑で難しい。
余談
今回の実験で使用した動画は、現在開発中の絵文字を入力するインプットメソッドの動作デモ。
日本人的には、OS標準の日本語IMやATOK、Google日本語入力等の日本語インプットメソッドを通じて絵文字の入力はある程度容易に、いつも通りの操作で行えるが、ふだんインプットメソッドを意識しないで文字入力している層(英語圏など)はどうしているんだろうか。わざわざ文字ビューアを起動して、検索して、選択して、とやっているのか——そういうところから着想を得て現在鋭意開発中。ふだん通りの入力操作の延長上で絵文字をかんたんに入力できる環境を目指します。
全世界の標準USインプットメソッドをこのEmoji IMで置き換えてやろうという野望を抱いています。
参考
2015年04月27日, 編集履歴

OS X用EPUBリーダMurasakiのver. 2.3をリリースしました。
ver. 2.3は、
- サイドバーメニューの実装。
- EPUB内コンテンツを統合したウィンドウの実装。
- Spotlight / Quick Lookプラグインの改良。
です。
サイドバーメニュー上で右クリック(Control
+ クリック)でコンテキストメニューが出るようになりました。サイドバーからコンテンツを新しいウィンドウで開いたり、階層付きナヴィゲーションを一度にすべて展開したり折りたたんだりできるようになりました。
EPUB内コンテンツ統合ウィンドウは、EPUB内のすべてのコンテントドキュメントを統合して一度に表示する特別なウィンドウです。コンテンツすべてを一度に選択、コピィ、印刷が行えます。ただし、統合ウィンドウではスタイルが多少崩れることがあります。今のところ横書きのみです。
Spotlight / Quick Lookプラグインの改良は「OS XのEPUB用Spotlight/Quick Lookプラグインを作り直した」で最初から書き直したものに差し替えました。当初はMurasaki v2系には同梱しない予定でしたが、OS Xの不具合が解消されたことにより古いMac OS Xにも対応できるようになりました。
2015年04月06日, 編集履歴
「迷惑メール相談センター」に迷惑メールを報告すると良いらしい(迷惑メールが減る)、という話を聞いたので実際にやってみた結果。
情報提供の方法
迷惑メール相談センターに情報提供することで、その情報は以下のように使われる(「提供いただいた情報について」より引用)。
提供いただいた違反情報については、総務大臣及び消費者庁長官による違反送信者への措置、電気通信事業者による送信防止対策に活用させていただきます。
迷惑メールの報告方法は、
- 迷惑メールの転送
- 迷惑メールを添付して送信
- フォームからの報告
である。
私はOS XのMail.appで受信した迷惑メールを「すべてを選択」した後、コンテキストメニューから「添付ファイルとして転送」した。

詳しい報告方法は、迷惑メール相談センターの「情報提供方法」を参照。
一年間報告し続けた結果
一年間、受信した迷惑メールを迷惑メール相談センターに毎日報告し続けた結果が以下のグラフと表である。グラフの横軸が受信した月、縦軸が月間受信数で、集計期間は2014年4月1日から2015年3月31日である。迷惑メールの報告をし始めたのは2014年3月半ば。

迷惑メール受信数
受信月 | account 1の受信数 | account 2の受信数 |
2014年4月 | 1099 | 973 |
2014年5月 | 1144 | 1148 |
2014年6月 | 1016 | 1065 |
2014年7月 | 1544 | 981 |
2014年8月 | 919 | 701 |
2014年9月 | 986 | 643 |
2014年10月 | 871 | 513 |
2014年11月 | 791 | 569 |
2014年12月 | 611 | 435 |
2015年1月 | 1150 | 828 |
2015年2月 | 664 | 484 |
2015年3月 | 694 | 477 |
「account 1」は2014年7月に突出した受信数を見せるが、8月、9月になると6月時点と同程度、その後減少し、2015年1月の増加を除いて、その後は微増あるいは横ばいという状態。「account 2」は2014年12月までは減少傾向が、2015年1月の増加を除いて、その後は横ばい状態が見られる。
「account 1」で見られる2014年7月の増加も、両アカウントで見られる2015年1月の増加も、一時的な増加であり次月には前月程度の数に収まっているのが特徴的である。これらの時期(年初を起点とした半年スパン?)が迷惑メール送信側にとってなんらかの意味がある時期なのかもしれない。
両アカウントとも、2014年7月、2015年1月を除いて、おおむね減少傾向が見られるのではないだろうか。集計期間の最初と最後である2014年4月と2015年3月で割合を見ると、「account 1」では約63%、「account 2」では約49%となった。
実験に使用したふたつのメールアカウントは、十年以上前にインターネットを利用し始めた時からの、インターネットプロヴァイダから提供されたものである。これらのメールアカウントはインターネット利用開始初期のよく解ってない時期に、いろんな(いま思えば怪しげな)懸賞サイト等に登録してしまったものである。現在は(迷惑メール収集を除いて)まったく使用していない。
2015年04月04日, 編集履歴
OS XのEPUB用Spotlight/Quick Lookプラグインを作り直した。
システム要件はとりあえずOS X 10.10以上。
上記のバイナリィダウンロードのページからZIPをダウンロード・解凍し、所定のパスへ配置することでインストール。Spotlightプラグイン(EPUB.mdimporter)は、
~/Library/Spotlight
(カレントユーザのみ)
/Library/Spotlight
(すべてのユーザ)
Quick Lookプラグイン(EPUB.qlgenerator)は、
~/Library/QuickLook
(カレントユーザのみ)
/Library/QuickLook
(すべてのユーザ)
プラグイン同梱版のMurasakiをインストールしている場合は、そちらが優先される可能性がある。そのときはFinderからMurasakiを選択して、コンテキストメニューの「パッケージの内容を表示」で中身を開いて、パッケージ内のLibrary
フォルダを削除もしくはリネームする。
プラグインをシステムに認識させるには、Macを再起動すると手数としては手っ取り早い。CLIが使えるならば、
$ mdimport -r /path/to/EPUB.mdimport
$ qlmanage -r
を実行する。
この新しいプラグインをいつMurasakiに同梱するかは未定である。
これまでMurasakiに同梱していたものと比べて、変更点は以下の通り。
Spotlightプラグイン
EPUB仕様のヴァージョン文字列(2.0とか3.0)をメタデータとして収集し、検索対象になった。メタデータの内部項目名は「com_genjiapp_Murasaki_mdimporter_EPUB_EPUBVersion
」で、表示名は「EPUB Version」および「EPUB バージョン」。たとえばターミナルで
$ mdfind "com_genjiapp_Murasaki_mdimporter_EPUB_EPUBVersion = '3.0'"
とすれば、EPUB仕様のヴァージョンが3.0
のもののみが検索できる。FinderウィンドウからのSpotlight検索ならGUIで条件指定可能。
Finderの「情報を見る」ウィンドウにEPUBのメタデータが表示されるようになった。

「情報を見る」ウィンドウでのプレヴューは表紙画像のみ。
Quick Lookプラグイン
各コンテントドキュメント(EPUB内部のXHTML)で指定されたスタイルをできるだけ保ちつつ、以前のものより表示品質を上げた(つもり)。コンテントドキュメントとしてXHTMLではなく画像ファイルが直接指定されているEPUBのプレヴューもできるようになった。

Spotlight検索からのQuick Lookプレヴューは以下のような感じ。Spotlight検索でEPUBだけを対象にしたい場合は、以下の画像のようにkind:epub
という条件を加えると良い。

赤線による強調は画像処理による。画像のようにEPUB内の単語でSpotlight検索できていることが解る。
style
要素のscoped
属性
Quick Lookでファイルをプレヴューさせる場合、プラグインはファイルの内容を取得・加工し、標準的な形式(画像やPDF、HTMLなど)にしてシステムに伝える必要がある。以前のものも今回のものも、EPUB内のコンテントドキュメント(多くの場合複数のXHTML)をひとつのHTMLにまとめ、システムに渡している。
各コンテントドキュメントをひとつにまとめる処理は以下のような感じになる。
- EPUBの
spine
で指定された読み順にしたがいコンテントドキュメントを読み込む
- コンテントドキュメントの内容を抜き出し、
div
要素に詰め込む
- 抽出された
div
をひとつのHTMLに順に並べる
ここで問題になるのが、各コンテントドキュメントで指定されているスタイルである。通常複数あるXHTMLコンテントドキュメントをひとつのHTMLにまとめているので、各コンテントドキュメントで指定されているスタイルが全体に影響を与えてしまう。(たとえば、本来ならば表紙ページにだけ適用されるべきスタイルがプレヴューされるHTML全体に適用される)。スタイル指定の記述を省くとまったくスタイルが当たっていない状態になるか、こちらで用意するスタイルを画一的に適用することになる。
そこで有望視しているのが、HTML 5で追加されたstyle
要素のscoped
属性である。style
要素にscoped
属性を付けることで、そのstyle
要素の親コンテナだけにスタイルを適用させることが可能になる。たとえば、
<p>...</p>
<div>
<style scoped="scoped"> p { color: red; } </style>
<p>...</p>
</div>
とすれば、div
内のp
要素だけにスタイルを適用できるようになる。
残念ながらWebKit(HTML形式のプレヴューではWebKitが用いられる)は現在scoped
属性に対応していない(確認した中ではFirefoxが対応している)が、今回のQuick Lookプラグインは各コンテントドキュメントのスタイル指定にscoped
属性を付けるようにした。
コンテントドキュメントの内容を抜き出す際、指定されているスタイル(style
要素の内容とリンクされているCSSファイルの内容)をscoped
属性を付けたstyle
要素に入れていっしょにdiv
に詰め込むようにした。そうやってひとつにまとめられたHTMLは以下のような形になる。
<html>
<body>
<div>
<style scoped="scoped">コンテントドキュメント1のスタイル</style>
...コンテントドキュメント1の内容...
</div>
<div>
<style scoped="scoped">コンテントドキュメント2のスタイル</style>
...コンテントドキュメント2の内容...
</div>
<div>
<style scoped="scoped">コンテントドキュメント3のスタイル</style>
...コンテントドキュメント3の内容...
</div>
</body>
</html>
WebKitがscoped
属性に対応していない現在では、各スタイル指定は各コンテントドキュメントの範囲を超えて全体に影響を及ぼす。その結果、表示に問題が出る可能性はあるが、EPUBの性質とリーディングシステムとの関係上、個別のコンテントドキュメントにあまり複雑なスタイルを当てることはあまりないはずで、これによる影響は少ないと思われる(少なくとも文字もののリフロー型では。固定レイアウト型は対象外)。
それよりも、まったくスタイルが適用されなかったり、あるいは画一的なスタイル指定ではなく、個別のEPUBごとの雰囲気を再現する方針をとっている。将来、WebKitがscoped
属性に対応すれば、スタイルの適用範囲が各コンテントドキュメントの範囲に限定されるようになるはずである。
2015年02月13日, 編集履歴

OS X 10.10 Yosemiteから搭載された機能拡張(通知センターの「今日」ペインで動作する機能拡張を「ウィジェット」と呼ぶ)を用いて、iTunesで再生中の曲にレート付けをするウィジェットを作ってみた。ソースはGenjiApp/iTunes-Rating-Widgetで公開する。
Scripting Bridge
iTunesからの情報取得や操作にはScripting Bridgeを用いた。Scripting BridgeはAppleScriptで操作可能なアプリケーションに対して、AppleScriptを用いずにObjective-Cからの操作を行うフレームワークである。
iTunesArtwork
オブジェクトの謎
Scripting Bridgeを用いてiTunesの曲情報を取得すると、アートワークはiTunesArtwork
オブジェクトとして得られる(クラス名等の接頭辞iTunes
は自分で設定可能)。このオブジェクトにはNSImage
型のdata
というプロパティがある。通常これを用いればCocoa環境で使いやすい画像オブジェクトが得られるはずである。
アートワークがJPEG形式の場合、data
プロパティは問題なくNSImage
が返すが、PNG形式だった場合、NSAppleEventDescriptor
オブジェクトが返ってくるという謎の挙動を示す。仕方がないので、iTunesArtwork
が持つ画像の生データrawData
プロパティを用いてNSImage
を生成した。
com.apple.iTunes.playerInfo
ノーティフィケーション
iTunesの再生・一時停止・曲送り・曲戻し操作の際には通知名「com.apple.iTunes.playerInfo
」で通知が飛ぶ。これをNSDistributedNotificationCenter
で捕まえて情報の更新を行った。
NSLevelIndicatorCell
のハイライト
NSLevelIndicator
を使うとiTunesのような星を用いたレート付けのGUIが作れる。しかし素のままで使うと、値が0
のときに表示が何もなくなって解りづらい。レート付けの操作中、つまりハイライト時にはドットが表示されるので、NSLevelIndicatorCell
をサブクラス化し、- (BOOL)isHighlighted
が常にYES
を返すようにしておいた。
コンテナアプリケーション
機能拡張はそれ単体では開発・配布を行うことができず、主となるアプリケーションが必要になる。これをコンテナアプリケーションと呼び、コンテナアプリケーションに内包する形で機能拡張を開発・配布することになる。
今回はそれは主眼ではないので、適当にシステム環境設定の機能拡張ペインを開くだけのものにした。システム環境設定の各ペインの実体は「/System/Library/PreferencePanes/
」以下にあるので、目的のペインのURLを作成し、NSWorkspace
のopenURL:
メソッドで開いてやれば良い。