2008-09-04
IE5〜IE7でも、RFC2397(Dataスキーム, DataURI)を使えるようにした!
JavaScript, canvas, uupaa.js, 問題
IE5,IE5.5,IE6,IE7 とおよそ10年に渡り、実装されなかった機能の一つに、Dataスキーム(DataURI) が あります。
uupaa.js version 0.6(近日中にリリース予定)では、DataURI をデコードする機能をエミュレートします。
DataURIって何
ラリーさんがRFC2397で提唱したデータスキームのこと。
ラリーさんってのはこの人。スパタさんにも見えるけどたぶん違う。
平たくいえば、
HTMLファイルに小さなアイコンや 1x1ドット のスペーサーを文字列化して埋め込める。
テキスト + アイコン数個で構成されるページなら、HTMLファイル1個だけで完結することもできるのが魅力。
# 小さな画像をチョコチョコ取得するのって、コスト高
# 負荷軽減の別解としては、小さな画像を1ファイルに敷き詰めて、CSS + clip で切り出して使う方法もあるけどね。
どうやって使うの
<html>
<head><title>DataURI test</title></head>
<body>
<div>
<img id="star" alt="star"
src="data:image/gif;base64,R0lGODlhDgAOANUAAP%2BZAP8A%2F%2Frx4v3Fb%2F6uNf%2F
FAPzaqf%2BmD%2F%2F%2F%2F%2F%2FXAP%2B0APzVk%2F60Qvr17f%2BsD%2Fvlw%2F%2Bt
AP%2FeAPzPgv27VPvivP60Of%2B4D%2F6mIP%2FMAP%2B%2BAP3HeP%2FnAP%2BlCPvr1Pr
59%2FzVnP%2BsC%2F%2B8C%2F%2BfCv6yMvvfs%2F%2BxFv%2B1Fv64Sfvq0QAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAACH5BAUUAAEALAAAAAAOAA4AAAZ5wIBwSKF4hsihZ1Q5JpEUk8n49FhHGEzTKv
RQPpqKIxJxnCQfSgMlChUSG3JBoTiIBB6JZcNPJApzIgNHHgsgcRFZdQtcAR4Tb38FEBONQ
lhZGBkQDE5dIgkZDg4QEBeeAQIiJRUPFBUHBw1IHQwkVlYGBKi4nrhCQQA7" />
</div>
</body></html>
<html>
<head><title>DataURI test</title></head>
<body>
<div>
<img id="larry" alt="larry"
src="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3
wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRN
zOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/TPg7JpJHxyendzWTBfX0cxOnKPj
gBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05
M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/X
l4/f1cf5VWzXyym7PHhhx4dbgYKAAA7" />
</div>
</body></html>
のように使います。
# 折りたたんでいるので、つなげて一行にしてください。
本当は、ほかにも使い道があって、
<style> list-style-image: url(data:image/gif;base64,R0lG...) </style> <script type="text/javascript" src="data:text/javascript;base64,....)
といったこともできるんだけどね。そこまでは実装していません。
今回サポートした機能
以下の条件をクリア場合のみDataURIが使えると思ってください。
結構厳しいことが書いてあります。
- 特別なこと
- data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw%3D%3D は 1x1の透明なドットのDataURI表現ですが、この文字列を見つけると特別にスペーサーGIFとして認識し、高さと幅に関する制限がなくなります(32x32以上でもOK)。
- 一度デコードしたGIFファイルのデータは一定期間キャッシュされ、同じ画像であればすばやく処理されます。
- style属性とwidth,heightでサイズを二重指定すると正しく解釈できません。二重指定しなければ混ぜても大丈夫です。
- img style="width:100px;height:100px" width="50" height="50" は、width=100px, height=100pxと解釈されるのが正しい仕様ですが、今回の実装では50px,50pxになります。理由はIEがimg.width, img.heightを勝手にバッテンアイコンのサイズに書き換えるのが原因です。
- 制限
- data:image/gif;base64 のみ対応。
- GIF87a, GIF89a の一部に対応
- GIF89a の
インターレースやアニメーションGIFが指定されると最初の1枚のみ表示 - 1ファイル当り
約1.3kBまでの画像をサポート(Base64化した状態で約2000byte)→ 約3kBまで(Base64化した状態で4kB)-
理由はIEのURL最大長が2083なので(http://support.microsoft.com/kb/208427/EN-US/)→ DetaURIとしてなら、4095文字まで使用可能なことが判明。かなり Hack ですけどね
-
- 推奨画像サイズは 16x16 〜 32x32
- 手作りのなんちゃってGIFとか、Trailer(0x3b)の後ろにHackなデータを詰め込んだ偽造GIFは一応大丈夫です。保障しませんが。
- お勧めの使い方
DataURI化は?
The data: URI kitchen でできます。
使い方は、
上記サイトでやってることは、C言語や perl でも10分もあれば出来ると思います。
ファイル読み込んでBase64化して標準出力に出すだけなので。
反省会
- DataURIがマイナーな存在なのは、IEが実装していないかったから、
- DataURIは使い方さえ間違えなければ、かなりお勧め。
- IE8β2でDataURIがサポートされているのに気が付いて作業を開始したので、GIFデコード込みで2日ほどか。
- MSがDataURIを無視し続けるんだったら、やらなかった。
- この10年だれもやらなかった理由は、実装してみて初めてわかった。
追記
- 2008-09-05
- VMLを多用するとIEのライフが簡単にゼロになるので、display="inline-block"を指定したspan要素の中に、絶対位置指定したdiv要素(おいおい)を、ドコドコ追加する方法に切り替えた。
- spanにdivを追加するのはimg要素の扱われ方(インライン要素なのに高さを持ちパディングが適用される)を再現するため。目的のために手段を問わないというか… 楽ではないのです。
- table + td だと横幅が必ず2pxになるのでだめだった。
- VMLを多用するとIEのライフが簡単にゼロになるので、display="inline-block"を指定したspan要素の中に、絶対位置指定したdiv要素(おいおい)を、ドコドコ追加する方法に切り替えた。
- 2008-09-06
- 単体のライブラリとしてリリースしました → http://d.hatena.ne.jp/uupaa/20080906/1220656835
- 2008-09-08
- version 1.0をリリースしました → http://code.google.com/p/uupaa-js-spinoff/
トラックバック - http://d.hatena.ne.jp/uupaa/20080904/1220462674
リンク元
- 7 http://reader.livedoor.com/reader/
- 4 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja:official&q=getContext+excanvas&btnG=検索&lr=lang_ja
- 2 http://b.hatena.ne.jp/add?mode=confirm&url=http://d.hatena.ne.jp/uupaa/20080904/1220462674
- 2 http://www.google.co.jp/search?hl=ja&q=new+image+javascript+onabort&btnG=検索&lr=
- 2 http://www.google.co.jp/search?hl=ja&rlz=1T4GZEZ_jaJP282JP282&q=javascript+xpath+node+検索&lr=
- 2 http://www.google.co.jp/search?q=JavaScript+excanvas&btnG=検索&hl=ja&lr=&sa=2
- 2 http://www.google.com/search?hl=ja&lr=lang_ja&ie=UTF-8&oe=UTF-8&q=coverflow+javascript&num=50
- 1 http://209.85.171.104/translate_c?hl=en&sl=ja&u=http://d.hatena.ne.jp/uupaa/20080723/1216748383&prev=/search?q=createElement(%27canvas%27)+excanvas&hl=en&client=firefox-a&rls=org.mozilla:en-US:official&sa=G&pwst=1&usg=ALkJrhg
- 1 http://b.hatena.ne.jp/mattn/favoritemobile
- 1 http://d.hatena.ne.jp/amachang/20080306/1204771762


