スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

はてなブログに引越し

今後ははてなブログを使っていこうと思います。

http://jou4.hateblo.jp/
スポンサーサイト

Googleプレゼンテーションをオフラインで

使いどころはそんなに無さそうですが…

自宅などでプレゼン資料を作成するのに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の仕様を把握できたのは収穫でした。

File APIを利用してファイルアップロード

「5000枚の写真をアップロードできるWebアプリがほしい」と無茶な依頼があったので、HTML5のFile APIを使ってサンプルを作ってみました。

サンプル)
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について説明されていたので試してみました。

適当にテストコードを書いてテストしてみます。

$ 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などを使えば、実行するテストの振り分けも思いのままですね。


といっても私にはファイル単位での指定でさしあたり十分な気がします(汗)
プロフィール

jou4

Author:jou4
FC2ブログへようこそ!

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。