1.023world - ヤドカリパークとマリンアクアリウム -

海洋の仕組みと細菌・微生物から学ぶマリンアクアリウムサイト

1.023world Facebook

結果 Oh! Life (旧ブログ)

懲りずに書いてみたりする結果オーライな日記

そろそろ透過PNG?

ウェブ@海水業界 エイジ 08:45

IE 7.0

IE 7.0 がリリースされてから、もうかれこれ2年以上が経過し、一方、IE 6.0 のシェアはそろそろ20%を切ったあたりだそうです。・・・って、まだ全然多いんですけど(汗)

とは言え、IE 7.0 になってから、ひとつだけ助かったことがあります。それは、24ビット PNG のアルファチャンネルに対応してくれたことです。これでようやく透過 PNG が貼れるようになりました。

透過PNGのサンプル

と言いたいところですが、まだ IE 6.0 ユーザーが残ってます。
そんなモン早く窓から放り投げてください(笑)

ちなみに IE 6.0 では、こんな風に表示されちゃいます。

透過PNGをIE6.0で表示した場合

なので、もし現時点で透過 PNG をウェブで使おうと思ったら、AlphaImageLoader フィルター(IE独自拡張)を活用せざるを得ないのが現状です。
(IE6ユーザーを切り捨てるなら話は別ですが)
幸いこれを使えば、辛うじて IE 6.0 でも透過 PNG を表示させることができます。

と言ってもコレ、ちょい面倒くさいんですよね。。。

AlphaImageLoader をどう使うか

例えば、透過 PNG を CSS の background 属性に限定して記述するなら、通常の background 属性の記述に続いて、filter 属性への AlphaImageLoader の設定と、アンダースコアハック(underscore hack)による background の消去を行うことで適用できます。(アンダースコアハックはIE6のみに適用させる場合に用いるハック方法)
但し、縦横のサイズが PNG と同一のレイヤに対しては問題ありませんが、PNG よりも大きなレイヤに背景として配置するような場合には注意が必要です。(AlphaImageLoader フィルターの sizingMethod オプションを crop にするか scale にするか等)

しかし、AlphaImageLoader フィルターを、HTML 内の <img> タグで貼られた透過 PNG に適用させる場合は、単に <img> タグに対して AlphaImageLoader フィルターを適用させただけでは、src 属性で指定された元々の PNG が残ったままなので、IE6 では相変わらず非透過の PNG が表示されたままとなります。これは外部 CSS ファイルで記述した場合でも、 <img> タグへ style属性で記述した場合でも同様です。そのため <img> タグの src 属性に透明 GIF を割り当てる等の最終処理が必要になります。そしてこの場合は何らかの JavaScript での処理に頼ることになります。

また、W3C に準拠した Valid でクリーンなソースを壊したくない場合や、ブラウザの独自拡張になるべくなら頼りたくない場合など、おかしなハックやコメントの記述をためらうこともあるでしょう。そう言う理由からも、このようなややこしい処理は初めからすべて JavaScript に丸投げする方法を推奨します。そうすることで、必要悪は最小限に抑えられるでしょう(苦笑)

ちょっと検索してみたら、この機能を持った JavaScript モジュールがいくつか配布されているようでした。ただ、実際にコードを見てみると、必要のない機能が多かったり、無駄にファイルサイズが大きかったりするので、PNG だけの処理には持てあますかも知れません。たかだか IE6 のためだけに資源を無駄に使うこともありませんし。

PNG → AlphaImageLoader 自動転換 JavaScript コード

そこで、PNG だけを処理してくれる JavaScript を組んでみました。(昔組んだものを少しいじっただけですが)
例によって、ページのヘッダに事前に読み込んでおくだけで、あとは自動的に処理してくれるものです。

このコードは、外部 CSS ファイルや HTML 内の <style> タグによる CSS や <img> タグの PNG をスキャンして、自動的に AlphaImageLoader を適用します。但し、<img> タグへの置換用に、予め透明 GIF をサーバーのどこかにアップロードして、ie-png.js 内の gif 変数に絶対パスで設定しておいてください。

変換対象
外部 CSS ファイル
  • background:url(PNG-URL) [color repeat position]
  • background-image:url(PNG-URL)
  • PNG 画像パスは自動的に解析し割り当てるので相対パスでもOK
  • PNG 画像パスをクオート(シングル・ダブル)で囲んであってもOK
内部 <style> タグによる CSS
  • background:url(PNG-URL) [color repeat position]
  • background-image:url(PNG-URL)
  • PNG 画像パスは自動的に解析し割り当てるので相対パスでもOK
  • PNG 画像パスをクオート(シングル・ダブル)で囲んであってもOK
<img> タグの PNG
  • 予め透明 GIF をサーバーにアップロードして、JavaScript コードにその透明 GIF 画像パス(絶対パス推奨)を設定してください
    var gif = 'アップロードした透明GIFの絶対パス';
  • PNG 画像パスは自動的に解析し割り当てるので相対パスでもOK

テスト結果:サンプルページ * IE 6.0 で見ないと効果が判りません
ダウンロード:ie-png.js

ひとりごと

確か、IE 6.0 だけじゃなくて、IE 5.5 とかにも AlphaImageLoader は使えたと思ったのですが、今手元の IETester で試してみると IE 5.5 では AlphaImageLoader による透過 PNG が表示されません(汗)
一応、コード自体は IE 5.5 でも走るように書いたつもりですが、もし動作確認がとれた方はご一報いただけると嬉しいです。

また、インライン CSS 分の画像パスや絶対パスによる記述分は良いとして、外部 CSS ファイル内の相対パスによる画像パスについて、なんかもっとうまく処理する方法はないかしら。例えば、外部 CSS ファイルを HTML とは別の階層から呼び出していた場合に、相対パスだと AlphaImageLoader に渡す画像パスがずれてしまうので、今は地道に生成するようにしてあります。

その他、background 関係以外の画像適用 CSS プロパティ(list-style-image とか)までは面倒なので実装を省略しました(汗)

以下、一応 ie-png.js のコードです。

var gif = 'null.gif';

var env = new Object;
env.ua = navigator.userAgent.toLowerCase();
env.win = (env.ua.indexOf('windows') != -1)? 1: 0;
env.ie = (!window.opera && env.ua.indexOf('msie') != -1)?
           Number(env.ua.charAt(env.ua.indexOf('msie ') + 5)): 0;

var url = new Object;
url.host = 'http://' + window.location.host;
url.path = window.location.pathname.replace(/^(.*?)/[^/]*$/,'$1') + '/';

function setOnload(func){
  (window.addEventListener)? window.addEventListener('load',func,false):
  (window.attachEvent)? window.attachEvent('onload',func):
  window.onload = func;
}

var checkPNG = {
  CSS: function() {   // background, background-image propaty only.
    if(!env.win || env.ie > 6 || env.ie < 5) return false;
    var path = new Array();
    var num = 0;
    var node = document.getElementsByTagName('head')[0].childNodes;
    for(var i=0;i<node.length;i++){
      if(node[i].nodeName.match(/^style$/i))
        path[num] = url.host + url.path;
      else if(node[i].nodeName.match(/^link$/i) &&
          node[i].getAttribute('rel') &&
          node[i].getAttribute('rel').match(/stylesheet/i)){
        var href = node[i].getAttribute('href');
        if(href.match(/^//)) path[num] = url.host + href;
        else if(!href.match(/^https?:///))
               path[num] = url.host + url.path +
                 href.replace(/^(([^/]*/)*).*?$/,'$1');
        else path[num] = href;
      }
      if(path[num]) num++;
    }
    for(var i=0;i<document.styleSheets.length;i++){
      var rule = document.styleSheets[i].rules;
      for(var j=0;j<rule.length;j++) {
        var png = checkStyle(rule[j],'background');
        if(!png) png = checkStyle(rule[j],'backgroundImage');
        if(!png) continue;
        png = (png.match(/^//))? url.host + png:
          (!png.match(/^https?:///i))? path[i] + png: png;
        rule[j].style['filter'] =
          'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' +
          png + ',sizingMethod=crop)';
      }
    }
    function checkStyle(obj,propaty){
      var value = obj.style[propaty];
      if(!value || !value.match(/.png/i)) return false;
      var png = value.replace(/^.*?url(["']*([^"']+.png)["']*).*$/i,'$1');
      obj.style[propaty] = '';
      return (!png.match(/^[^"']+.png$/i))? '': png;
    }
  },
  HTML: function(){   // '<img>' elements only.
    if(!env.win || env.ie > 6 || env.ie < 5) return false;
    var img = document.getElementsByTagName('img');
    for(var i=0;i<img.length;i++){
      var src = img[i].getAttribute('src');
      if(!src.match(/.png/i)) continue;
      if(!src.match(/^https?:///i)) src = url + src;
      img[i].setAttribute('src',gif);
      img[i].style.filter =
        'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' +
        src + ',sizingMethod=scale)';
    }
  }
}

function onloads(){
  checkPNG.HTML();
}

checkPNG.CSS();

setOnload(onloads);

こちらのエントリーもどうぞ♪

コメントとトラックバック

  1. 1. わもん 2009/03/23 10:48

    最近の話は申し訳ないですが、ほとんどチンプンカンプンです(汗)

    それはそうと、ヤドカリストでマイヤドカリログを「公開」にしてみたんですが、なぜか古いほうの合格歴が登録されてしまうようです。(1級と2種の場合、1級になってしまいます)

    それと、僕のブログのほうで指摘してもらった問題で、ゆーいちさんにも同じことを指摘されたんですが何がおかしいのかわかりません(汗)

    「txt」になってるから「html」に変更するようにということですが、ファイルを「名前を付けて保存」する時に「ファイルの種類」が「txt」と「すべての種類」しかなく、どちらで試しても結果は同じになります。

    パソコンに詳しいお二人からの指摘なのに、他の人にはちゃんと見れてるようなので何がおかしいのか余計に謎なんですが(汗)

  2. 2. ゆーいち 2009/03/23 15:54

    んと、ここで返信っとw

    えっとですね
    名前をつけて保存のとこで
    すべての種類を選択して○○.htmlとして保存するか
    もしくは、一度txtで保存した後に、名前の変更で.txtから.htmlに
    変更するだけでOKですよん!

  3. 3. ゆーいち 2009/03/23 16:01

    IETesterなんて便利なもんがあったとですねorz
    どうせならブラウザテスターなんてのもあったら便利なんですがねぇ(;´Д`)
    IE全バージョン、FireFox、Opera、Safari、etc…
    探せばあるのかな?

  4. 4. わもん 2009/03/23 18:39

    ゆーいちさん
    「すべての種類」の中にhtmlがなく、
    名前の変更でも端子の部分が変更できません(>_<)

    直さないとやっぱり都合悪いですかね?(汗)

  5. 5. ゆーいち 2009/03/23 20:58

    あっ
    もしかして拡張子って表示させてないです?
    txtとかjpgとかって表示されてなかったりします?
    だとしたら、http://windowshelp.microsoft.com/Windows/ja-JP/help/a0b4607a-6fa8-42ab-aef6-7418183389da1041.mspx
    ここのやり方を見ながら拡張子を表示するようにして、
    その後、各当するファイルの拡張子を名前の変更から
    ○○.txtから、○○.htmlに変更出来るはずです~
    あと、保存の際のすべての種類ってところにhtmlは表示されてないので
    自分で名前を入力するところで○○.htmlとして保存すればOKですよ~。

  6. 6. わもん 2009/03/23 21:53

    ゆーいちさん、おおきにです!
    おかげ様でなんとか変更できました(^^;

    これって変更しないとどう都合が悪いんでしょうかね?

  7. 7. ゆーいち 2009/03/23 22:19

    えっとですね
    普通はtxtファイルはHTMLとは違いまして
    ただのノートで書き出したテキストでして。
    ブラウザによってはtxtファイルはあくまでテキストなので
    書かれた内容がそのまま見えてしまうんです。
    IEでなんで表示されたのかは謎ですが…
    で書かれた内容物に関しては
    .htmlとして保存しないとブラウザで認識されないのが通常なんですが
    ん~FC2でなんらかの変換でもしてるのかなぁ…

    試しに自分で作ったあのヤドカリの奴を
    txtの時と、htmlとを
    IE立ち上げて、ブラウザが表示される部分に
    ファイルをドラッグしてもらうと
    謎が多分解けると思いますw

  8. 8. エイジ 2009/03/24 06:54

    わもんさん、

    ヤドカリ検定は資格毎に資格番号が異なるので、ログインするときに古い方の資格番号でログインすると、当然古い方の管理パネルになります。
    新しい方の資格番号とその時のパスワードでログインすれば、新しい方の管理パネルに繋がります。
    なお、一度ログインするとブラウザを終了するまでその管理パネルにしか繋がらないので、ログイン後に別の資格番号でログインしたいときは、一度ブラウザを終了させる必要があります。

    あと、txtとhtmlの件は、無事解決したようで何よりです。

    ゆーいちさん、

    IETesterでは、IE5.5、IE6、IE7、IE8での確認ができます。
    また、他のブラウザについても、最近どこかで読みました(どこだったか失念)が、海外だったかでFirefoxやその他のブラウザチェックができるツールが出るとかどーとかあるらしいです。有料ですが、IEの各バージョンだけの体験版もあるとか。
    どこで読んだかなぁ。。。最近物忘れが激しくて(汗)

    あと、IEは昔から拡張子を無視してファイルデータ優先で表示するクセ(?)があります。
    例えば、GIF画像のように、ファイルの先頭に「GIF89a」と書かれていれば、それがtxtだろうとhtmlだろうと、画像として表示しようとします(曝)
    ちなみにこの場合、パソコン上では拡張子を優先するらしく、ちゃんとテキストファイルで表示します。サーバーにアップするとそうなります。
    今試してみたら、最近出たIE8でもそうなりました。直す気ないみたい(笑)
    サーバーが返すContent-typeを無視するのはIEくらいですよね。
    もちろん他のブラウザはそんなバカな解釈はしないので、ちゃんとテキストとして表示します。
    お試しアレ。

    > IE立ち上げて、ブラウザが表示される部分に
    > ファイルをドラッグしてもらうと
    > 謎が多分解けると思いますw

    上記のように、ローカルだと謎は解けないかも。サーバーにあげないと。

  9. 9. ゆーいち 2009/03/24 09:27

    おはよございます~
    あぁ~あるんですね~それなりにチェッカーってw
    あと、
    > IE立ち上げて、ブラウザが表示される部分に
    > ファイルをドラッグしてもらうと
    > 謎が多分解けると思いますw
    これですが、ローカル環境で試すとIEでもテキストファイルで
    表示されるんで、他のブラウザだとそう見えるんですよ~ってことでw

  10. 10. エイジ 2009/03/24 20:08

    > 他のブラウザだとそう見えるんですよ~ってことでw

    なるほど。僕の早とちりでした。

  11. 11. わもん 2009/03/25 00:25

    エイジさん、

    ログインし直して無事変更できました。
    またあとで観察歴を新しく更新しておきます~

    ゆーいちさん、

    恥ずかしながら、IEとブラウザの意味を調べて今頃やっと理解できました(汗)
    試しに早速Firefoxを導入して自分のブログを見てみたら、
    見れないブログパーツが多いことにびっくりしました!

    初心者としての感想ですが、ベテランさんは勝手に変換してしまうIEに苛立ちを覚えるでしょうが、ほとんどのユーザーは僕と同じで他にブラウザがあるのを知らないで使っている人が多いと思うので、逆にIEは初心者向けに優しくできてるのかな? などと思ったりします。

    実際、Firefoxを使ってみましたが、初めてで使い勝手が変わって戸惑ったのと、自慢?の速さを実感できなかったり・・・

    やはり他のブラウザはベテラン向きなのかな?と感じました(汗)

  12. 12. エイジ 2009/03/27 09:38

    わもんさんの言うとおり。
    ほとんどの方はWindowsに付属のIEをそのまま使ってますね。
    だから僕らはまだまだ耐えなければならない(汗)
    仕方がないので、こゆの読んで和んでます。
    http://builder.japan.zdnet.com/news/story/0,3800079086,20385564,00.htm

  13. 13. raho 2009/04/14 20:43

    はじめまして。
    かなり遅いレスで失礼します。
    IETesterとPNG透過についてですが、既に解決されておりましたら申し訳ない。
    私も最近透過PNGを使うサイトを作りまして、同じくIETesterで動作確認をしていたのですが、どうもうまく表示されず…
    もしやIETester自体に問題があるのではと思い、WindowsXPのマシンで正規IE6を使用し確認したところ、思ったとおり、正しく透過PNGを表示できていました。
    どうやらIETesterがAlphaImageLoaderに対応してなさそうな感じです。
    Javascript関係もちょっと怪しい動きをしますし、あまり過信しない方がいいかも知れません…
    ただ確認作業が楽ちんですごく助かっているので、バージョンアップに期待したいです。

  14. 14. エイジ 2009/04/15 03:43

    rahoさん、はじめまして。
    コメント&ご報告ありがとうございます。

    僕の方はあれから特に進展がありませんが(と言うか忘れてましたが)、IETesterのIE6モードなら、当初からAlphaImageLoaderによるPNG表示は成功していますよ。
    ダメなのは、IETesterのIE5.5モードでのPNG表示です。
    IETesterのバージョンは今すぐ判りませんが、当時で最新のものだったと思います。黄色い交通標識のようなアイコンだったかな?

    ちなみにrahoさんのご報告内容は、WinXP+IE6+AlphaImageLoaderによるPNG表示ですよね?
    AlphaImageLoaderを使わないとIE6はオリジナルでもPNGのアルファチャンネルは表示できないはずですので。

    JavaScriptに関しては、確かにIETesterは頼りないですよね。
    そのせいで躓いているのかも知れません。
    便利ですし唯一のテスターですけど、元はと言えばMicrosoftのせいです(汗)

  15. 15. maru 2009/05/21 04:00

    はじめまして。
    IEtesterとpng(透過)の検索でたどり着いた者です。

    なぜこのワードで検索をしていたかと申しますと、PNGが
    ローカルでは透過されるのですが、サーバへアップされると
    表示されない。という、現象に陥った為です・・・。
    あいにく私の環境がIE7,8で6の環境がなく、表示されない原因が
    分からずグーグルさんとにらめっこしておりましたwww

    幸い、モバイルPCの環境が6だという事を思い出し
    確認したらブラウザ上では透過されておりました。

    ■環境
    cssによる背景を透過pngを使用。
    重なるイメージはpngどうしではなく、jpgの上にpngを表示。

    IEtesterを頻繁に使っている者の落とし穴みたい感じでした・・・。

    エイジさんも、過去に同じ様なことはありませんでしたか?
    なければあれば、IEtester上で透過が確認できなければ
    正規のIE6ブラウザで確認することをおススメ致します。

    ※上部でも書かれていましたがIE6は。早くなくなればいいのにですねww

  16. 16. エイジ 2009/06/12 04:44

    maruさん、コメントありがとございます。
    遅くなってごめんなさい。

    > IEtesterを頻繁に使っている者の落とし穴みたい感じでした・・・。

    そんなこともあるのですね。。。僕は経験がありませんでした。
    でも別の不具合で、IETesterのIE8で変だったものが、正規のIE8では何ともないケースは確かにありましたね。気を付けなければ!
    貴重な情報をありがとうございます。

    ちなみに最近手がけたウェブでは、試しにIE6をスルーし始めています。
    とても作りやすいです(苦笑)

コメントフォーム