Googleプレゼンテーションをオフラインで
使いどころはそんなに無さそうですが…
自宅などでプレゼン資料を作成するのにGoogleプレゼンテーションをよく利用しています。
アニメーションなどに凝らない簡単な資料ならこれで十分です。
ただ先日インターネットに繋げない状況でプレゼンする機会があったのですが、オフライン時にスライドショーを実行する方法が見当たらない。作成や編集はまあ仕方ないですけど。
そこでエクスポート機能を使ってPDFやPPTファイルへの変換を試みましたが、微妙にフォントサイズが違うなど、資料が崩れてしまったり。
資料を崩さず、かつオフライン時にスライドショー形式で実行できたらいいのにと思ったので、Chromeの拡張機能でスライドショーを再現できるようにしてみました。
https://github.com/jou4/goopre
binディレクトリのcrxファイルをChromeにドラッグ&ドロップすれば使えるようになります。
使い方ですが、保存は…
1. Googleプレゼンテーションでスライドショーを実行
2. 拡張機能のアイコンをクリック
3. 「このスライドショーを保存」をクリック
(オンラインで行う必要があります)
続いてスライドショーの実行は…
1. 拡張機能のアイコンをクリック
2. 実行したいスライドショーの名前をクリック
やっていることは単純です。
・スライドショーの実行に必要なデータを抜いてローカルストレージへ保存
・画像データはデータスキームURIへ変換して埋め込む
・そのデータを利用してスライドショーを実行
もしかしたらフォントサイズなどで完全には再現できない箇所もあるかもしれません。自分の手元の資料は一応OKでしたが。
また、背景画像や図形、動画などには現在対応できていません。
自宅などでプレゼン資料を作成するのにGoogleプレゼンテーションをよく利用しています。
アニメーションなどに凝らない簡単な資料ならこれで十分です。
ただ先日インターネットに繋げない状況でプレゼンする機会があったのですが、オフライン時にスライドショーを実行する方法が見当たらない。作成や編集はまあ仕方ないですけど。
そこでエクスポート機能を使ってPDFやPPTファイルへの変換を試みましたが、微妙にフォントサイズが違うなど、資料が崩れてしまったり。
資料を崩さず、かつオフライン時にスライドショー形式で実行できたらいいのにと思ったので、Chromeの拡張機能でスライドショーを再現できるようにしてみました。
https://github.com/jou4/goopre
binディレクトリのcrxファイルをChromeにドラッグ&ドロップすれば使えるようになります。
使い方ですが、保存は…
1. Googleプレゼンテーションでスライドショーを実行
2. 拡張機能のアイコンをクリック
3. 「このスライドショーを保存」をクリック
(オンラインで行う必要があります)
続いてスライドショーの実行は…
1. 拡張機能のアイコンをクリック
2. 実行したいスライドショーの名前をクリック
やっていることは単純です。
・スライドショーの実行に必要なデータを抜いてローカルストレージへ保存
・画像データはデータスキームURIへ変換して埋め込む
・そのデータを利用してスライドショーを実行
もしかしたらフォントサイズなどで完全には再現できない箇所もあるかもしれません。自分の手元の資料は一応OKでしたが。
また、背景画像や図形、動画などには現在対応できていません。
PHPでExifを埋め込む
Exifが削られた写真に再度撮影日付を埋め込む必要があったのですが、めぼしいライブラリがライセンス的にうんぬんってことだったので利用を見送ることに…
そこで簡易的なコードをPHPで書いてみました。
https://gist.github.com/1196871
とりあえず動いてそうだけどどうだろ。
書くにあたり以下のサイトを参考にさせていただきました。
Exif形式の画像ファイル解説
バイナリエディタとのにらめっこはきつかったですが、Exifの仕様を把握できたのは収穫でした。
そこで簡易的なコードをPHPで書いてみました。
https://gist.github.com/1196871
とりあえず動いてそうだけどどうだろ。
書くにあたり以下のサイトを参考にさせていただきました。
Exif形式の画像ファイル解説
バイナリエディタとのにらめっこはきつかったですが、Exifの仕様を把握できたのは収穫でした。
File APIを利用してファイルアップロード
「5000枚の写真をアップロードできるWebアプリがほしい」と無茶な依頼があったので、HTML5のFile APIを使ってサンプルを作ってみました。
サンプル)
http://5463440d.dotcloud.com/
ソースコード)
https://github.com/jou4/multi_fileupload
※上のサンプルは、サーバーが受け取ったファイルを保存しないのでアップするだけのものです。
※またリクエストのサイズも制限されているので、大きなファイルはアップできません。
ドラッグ&ドロップは、ondragover, ondragend, ondropといったイベントで制御します。
jQueryを使うのであれば、bindメソッドを利用してこんな感じでしょうか。
ドロップされたら、ファイルオブジェクトのリストをevent.dataTransfer.filesで取得できますが、jQueryの場合だとイベントオブジェクトがラップされているので、originalEventで取り出す必要があります。
ファイル選択ダイアログを利用する場合は、multiple属性を付与することで複数選択が可能になります。
ダイアログで選択されたらchangeイベントが発生します。要素を指定してfilesでファイルオブジェクトのリストを取り出します。
ファイルの読み出しにはFileReaderを使用します。画像ファイルの場合だとこんな感じ。
readAsDataURL以外にもいくつかメソッドがありますので状況に応じて使い分けることになります。
今回は大量のファイルをアップロードすることが目的なので、一度に送信せず1ファイルずつ送信するようにしました。FormDataを使ってフォーム送信が可能になります。こんな感じです。
最後に、マルチスレッド風に並列で送信できるようにしてみました。指定されたファイルリストをいくつかのリストへ分割して、それぞれのリストを担当するループを作成する感じです。並列化するとやはり速くなりますね。ざっくりですが並列数=1を基準としたとき、並列数=2で2倍、並列数=3で3倍、並列数=4で3.5倍、並列数=5で4倍になりました。マシンのスペックなどに依存すると思いますので、一概にはいえませんが。
以前Flashを使って、同じようなアップローダーを作成したことがあるのですが、そのときはFileReferenceクラスのbrowseやload、uploadといったメソッドを同時に実行できないといった制限があったので、こういった並列化をしなかった覚えがあります。
まだ対応しているブラウザはChromeとFirefoxといったところだと思いますが、
とりあえず「5000枚の写真をアップロード」という要求には答えられそうです♪
サンプル)
http://5463440d.dotcloud.com/
ソースコード)
https://github.com/jou4/multi_fileupload
※上のサンプルは、サーバーが受け取ったファイルを保存しないのでアップするだけのものです。
※またリクエストのサイズも制限されているので、大きなファイルはアップできません。
ドラッグ&ドロップは、ondragover, ondragend, ondropといったイベントで制御します。
jQueryを使うのであれば、bindメソッドを利用してこんな感じでしょうか。
$("#holder")
.bind("dragover", function(){
this.className = 'hover';
return false;
})
.bind("dragend", function(){
this.className = '';
return false;
})
.bind("drop", function(e){
this.className = '';
handleFiles(e.originalEvent.dataTransfer.files);
e.preventDefault();
return false;
});
ドロップされたら、ファイルオブジェクトのリストをevent.dataTransfer.filesで取得できますが、jQueryの場合だとイベントオブジェクトがラップされているので、originalEventで取り出す必要があります。
ファイル選択ダイアログを利用する場合は、multiple属性を付与することで複数選択が可能になります。
<input id="selector" type="file" name="file[]" multiple />
ダイアログで選択されたらchangeイベントが発生します。要素を指定してfilesでファイルオブジェクトのリストを取り出します。
$("#selector").change(function(){
handleFiles(this.files);
});
ファイルの読み出しにはFileReaderを使用します。画像ファイルの場合だとこんな感じ。
var reader = new FileReader(), img = document.getElementById("image");
reader.onload = function(e){
img.src = reader.result;
};
reader.readAsDataURL(file);
readAsDataURL以外にもいくつかメソッドがありますので状況に応じて使い分けることになります。
今回は大量のファイルをアップロードすることが目的なので、一度に送信せず1ファイルずつ送信するようにしました。FormDataを使ってフォーム送信が可能になります。こんな感じです。
var fd = new FormData();
fd.append("file", file);
$.ajax({
url: "hogehoge",
type: "POST",
data: fd,
processData: false, // dataをそのまま送信させる
contentType: false,
success: function(){}
});
最後に、マルチスレッド風に並列で送信できるようにしてみました。指定されたファイルリストをいくつかのリストへ分割して、それぞれのリストを担当するループを作成する感じです。並列化するとやはり速くなりますね。ざっくりですが並列数=1を基準としたとき、並列数=2で2倍、並列数=3で3倍、並列数=4で3.5倍、並列数=5で4倍になりました。マシンのスペックなどに依存すると思いますので、一概にはいえませんが。
以前Flashを使って、同じようなアップローダーを作成したことがあるのですが、そのときはFileReferenceクラスのbrowseやload、uploadといったメソッドを同時に実行できないといった制限があったので、こういった並列化をしなかった覚えがあります。
まだ対応しているブラウザはChromeとFirefoxといったところだと思いますが、
とりあえず「5000枚の写真をアップロード」という要求には答えられそうです♪
lein testについて
leiningenのtutorialにlein testについて説明されていたので試してみました。
適当にテストコードを書いてテストしてみます。
次にファイルを追加してみます。
hooke.jarというのを利用すればさらに細かく指定できます。
次のような感じで使います。
「lein test」とした場合は「:default」で指定したテストが実行されます。
ファイル指定との組み合わせも可能です。
deftestで記述した「{:category-1 true}」というマップがそのまま:test-selectorsの各関数へ渡されるようです。orやnotなどを使えば、実行するテストの振り分けも思いのままですね。
といっても私にはファイル単位での指定でさしあたり十分な気がします(汗)
適当にテストコードを書いてテストしてみます。
$ lein new myproject
;; test/myproject/test/core.clj
(ns myproject.test.core
(:use [myproject.core] :reload)
(:use [clojure.test]))
(deftest test-1
(is (= (+ 10 20) 30))
(is (= (- 20 5) 15)))
$ lein test
次にファイルを追加してみます。
;; test/myproject/test/sample.clj
(ns myproject.test.sample
(:use [myproject.core] :reload)
(:use [clojure.test]))
(deftest test-2
(are [x y] (= x y)
6 (* 2 3)
2 (/ 6 3)))
;; 全てテスト
$ lein test
;; ネームスペースを指定して個別にテスト
$ lein test myproject.test.core
$ lein test myproject.test.sample
;; 複数も指定できる
$ lein test myproject.test.core myproject.test.sample
hooke.jarというのを利用すればさらに細かく指定できます。
;; test/myproject/test/core.clj
(deftest ^{:category-1 true} test-3
(is (= (+ 10 20) 30)))
(deftest ^{:category-2 true} test-4
(is (= (+ 10 20) 30)))
;; project.clj
:dev-dependencies [[robert/hooke "1.1.0"]]
:test-selectors {:default (fn [v] (or (:category-1 v) (:category-2 v)))
:category-1 :category-1
:not-category-1 (fn [v] (not (:category-1 v)))
:all (fn [_] true)}
次のような感じで使います。
$ lein test :category-1
$ lein test :all
「lein test」とした場合は「:default」で指定したテストが実行されます。
ファイル指定との組み合わせも可能です。
$ lein test :category-1 myproject.test.core
$ lein test :all myproject.test.core myproject.test.sample
deftestで記述した「{:category-1 true}」というマップがそのまま:test-selectorsの各関数へ渡されるようです。orやnotなどを使えば、実行するテストの振り分けも思いのままですね。
といっても私にはファイル単位での指定でさしあたり十分な気がします(汗)
vimclojureのインストール
最近emacsからvimに乗り換えようか迷い中です。
試しにclojureの開発環境を作ってみようとvimclojureのインストールについて調べてみました。
ホームページらしきページがアクセスできなくて焦りましたが、READMEを読めば問題なく設定できました。
作業はubuntuで行いました。
clojureやleiningenのインストールについては特に触れません。
まずはvimclojureをチェックアウトします。
(zip等でのダウンロードも可能です。)
ngサーバーへ接続するためのngクライアントをmakeしておきます。
続いて.vimの下へプラグインを置きます。
(私はpathogen.vimを使っているのでbundleの下へ置きました。)
ftdetectだけは.vim直下へ置かないとfiletypeを特定できないようなので移動します。
.vimrcへ追記します。
それではサンプルのプロジェクトを作ってみます。
project.cljに追記します。
依存するjarファイルダウンロードします。
ngサーバーを起動して、コードを書いてみます。
<LocalReader>etでevalできます。
REPLの起動は<LocalReader>srです。
:help clojure.vimを見ると他にもいろいろ書いてあります。
そのままだとngサーバーの起動が面倒だったのですが、lein-vimclojureというプラグインのおかげで
「lein swank」みたいに起動できて助かります。
[追記 2011/03/29]
後日MacOSXでも同じ設定を行ったのですが、日本語の混じったコードをevalできませんでした。
どうやらMacのJDK6からデフォルトShift_JISになったようで以下の環境変数をセットすれば動くようになりました。
試しにclojureの開発環境を作ってみようとvimclojureのインストールについて調べてみました。
ホームページらしきページがアクセスできなくて焦りましたが、READMEを読めば問題なく設定できました。
作業はubuntuで行いました。
clojureやleiningenのインストールについては特に触れません。
まずはvimclojureをチェックアウトします。
(zip等でのダウンロードも可能です。)
$ sudo aptitude install mercurial
$ hg clone https://bitbucket.org/kotarak/vimclojure
ngサーバーへ接続するためのngクライアントをmakeしておきます。
$ cd vimclojure/client/
$ make
続いて.vimの下へプラグインを置きます。
(私はpathogen.vimを使っているのでbundleの下へ置きました。)
$ cd ../
$ cp -R vim/ ~/.vim/bundle/vimclojureftdetectだけは.vim直下へ置かないとfiletypeを特定できないようなので移動します。
$ cd ~/.vim
$ mv bundle/vimclojure/ftdetect ./.vimrcへ追記します。
syntax on
filetype plugin indent on
let vimclojure#WantNailgun = 1
let vimclojure#NailgunClient = "/path/to/ng" " 先にmakeしたngクライアントのパス
let vimclojure#HighlightBuiltins = 1それではサンプルのプロジェクトを作ってみます。
$ cd hoge
$ lein new sample
$ cd sampleproject.cljに追記します。
:dev-dependencies [[vimclojure/server "2.2.0"]
[org.clojars.autre/lein-vimclojure "1.0.0"]]依存するjarファイルダウンロードします。
$ lein depsngサーバーを起動して、コードを書いてみます。
$ lein vimclojure &
$ vim src/sample/core.clj
(+ 1 2 3)<LocalReader>etでevalできます。
REPLの起動は<LocalReader>srです。
:help clojure.vimを見ると他にもいろいろ書いてあります。
そのままだとngサーバーの起動が面倒だったのですが、lein-vimclojureというプラグインのおかげで
「lein swank」みたいに起動できて助かります。
[追記 2011/03/29]
後日MacOSXでも同じ設定を行ったのですが、日本語の混じったコードをevalできませんでした。
どうやらMacのJDK6からデフォルトShift_JISになったようで以下の環境変数をセットすれば動くようになりました。
export _JAVA_OPTIONS="-Dfile.encoding=UTF-8"


