svgzはファイル形式で説明するならテキストベースのsvgファイルをgzip形式で圧縮したものである.従って,javascriptによるgzip形式への圧縮が出来ればそれで終わりとなるはずだ.gzip圧縮そのものは標準規格であり,その実装としては様々なものが考えられるが,中でも有名なライブラリの一つにzlibがある.zlibのソースコードはcで書かれていてフリーソフトウェアとして一般に公開されているため,このzlibをjavascriptに移植するのが正攻法と言える.
一方,gzipが広範な分野で利用されている事を鑑みると,既に似たような事をしている方がいてもおかしくないので調べてみたところ,概ね下の3つあたりが引っかかってきた.(「javascriptで圧縮」と「javascrptを圧縮」が混ざって検索が色々と面倒だったのは秘密だ.)
- 高度な JavaScript 技集
古くから公開されている圧縮・解凍ライブラリ.なお,zlib.jsは現在作成中とのこと.
- pure JavaScript の Zlib, Deflate 実装を作りました
byte配列からpng画像ファイルを生成するライブラリ.内部で画像の圧縮をするためにzlibの機能を実装している. - Jsziptools
zip,gzip形式の圧縮・解凍ライブラリ.
- 圧縮アルゴリズム適用時は数値データの配列として扱う.
- 1バイトデータ毎にString.fromCharCodeを使って文字列型に変換する.
- 上の文字群を結合して1つの文字列データを取得する.
例)data:application/x-gzip;base64,[base64形式のバイナリデータ]
このa要素やimg要素を経由してjavascriptによる圧縮結果をブラウザ外部に取り出すことが可能となるのだ.
と,大体はこの流れで済むのだが,ここからが面倒だった.
- 高度な JavaScript 技集
ライブラリにバグが存在する模様で,圧縮するファイルのサイズが大きくなると外部ツールによる解凍結果が壊れる. - pure JavaScript の Zlib, Deflate 実装を作りました
圧縮処理は為されるものの,png画像生成に特化しているため,gzipに必要となるヘッダーが付加されないため,生成したデータがsvgz形式として不正となる.
そこで Jsziptoolsである.このライブラリはhtml5で追加されたblobオブジェクトを用いて先ほどのようなバイナリ-文字列の不安定な相互変換を完全に隠蔽しており,使い方も明快だ.例を示す.
function getSVGZUrl(){
var URL = window.URL || window.webkitURL;
var svg = getSVGSource();
var gzbuff = jz.gz.compress(jz.utils.stringToArrayBuffer(svg));
var bb = new jz.BlobBuilder();
bb.append(gzbuff);var d = bb.getBlob();
return URL.createObjectURL(d);
}
インラインsvgのソースコードは,そのsvg要素を囲んでいるhtml要素のinnerHTMLプロパティを参照することで取り出すことが出来る.その際は若干スタンドアロンのsvgとして不足している部分(xlinkが落ちるとか,xml宣言が足りないとか)があるので,補うことを忘れずに.
最後の部分で生成されているのがblobオブジェクトへのリンク文字列(キー情報)で,この値をa要素のhref属性に設定することでjavascript内部のバイナリを直接ブラウザ外部に取り出すことが可能となる.無用な文字列形式への変換を経由しない分動作も軽快で,chromeで引っかかるdataスキームの長さ制限(経験的だが1MBを超過するとクラッシュする)も考慮せずに済む.
実際にsvgzを出力してみたが,inkscapeやその他のツールでも正しくグラフィックが展開された.どうやらgzip形式として正しいようだ.
このように非常に強力なライブラリなのだが,一点注意すべき点がある.現在利用可能な環境が狭いということだ.firefox,chrome(及びie10)とのことで,それ以外のブラウザでは動作しないのだ.現状でも基底となるオブジェクト群がベンダプレフィクス付きであり,将来的にapiが変更となる可能性も否定できない.
と言ったわけで,積極的に利用するにはちょっと時期尚早の感はあるが,早速potraceHtmlに組み込んでみた.本当に最近のブラウザは既にアプリケーションプラットフォーム化しているんだなぁと.
0 件のコメント:
コメントを投稿