IEの画像縮小がきれいに表示されない理由

システム部渋谷です。

このごろはレスポンシブデザインでのWeb制作が当たり前のようになってきました。
レスポンシブデザインでは閲覧環境に合わせて見え方を変える都合上、大きな画像を用意してそれをブラウザ上で縮小させて表示することになります。

「レスポンシブで縮小した画像がIEだけ汚い…」

古いIEが消えてだいぶましな描画がされるようになったほのぼのIEだったのですが、またしても問題に!

berry

この画像を各ブラウザで縮小してみてみると…

hikaku

あたかもニアレストネイバーで縮小したかのような汚さなのですが……。
(縮小したものをニアレストネイバーで2倍に拡大しています)

各ブラウザの画像補完について

どういう処理をしているのかを調べるために、画像を縮小拡大になんのアルゴリズムを使ってるのか見てみました。

kakudai

上の画像は、小さい画像を大きく表示させた場合どう表示されるかを表したものです。
8×8の小さな画像を256×256に引き延ばしています。
上段はPhotoshopで作った参考画像で、下段は各ブラウザでの表示結果。

もしかしたら画像によって、または縮小と拡大によって切り替えているかもしれませんが、
IE11:バイリニア
Edge:バイリニア
Chrome:バイキュービック
Firefox:バイリニア
という結果でした。
バイリニア以上を各ブラウザがデフォルトとして使ってることは確定のようなのでそんな汚くならないと思うんだけどなぁ…と。

今度は別な画像を使っての縮小テスト。
しましまな横512の画像を横63に縮小表示させています。
割り切れない微妙な数字にするのがポイント。

shukushou

IEとEdgeだけ妙な縞になってます。

バイリニアでは求める位置のピクセルと周囲の1ピクセルを線形的に補完するため、半分以下の大きさに縮小する場合一度半分の大きさにして、そこから再帰的に小さくしていかないときれいな画像になりません。
(無視して捨てられるピクセルがたくさん出てくる)

元の画像が大きければ大きいほどニアレストネイバーに表示結果が近づいていくことになります。
そのぶん処理は軽くなりますが。

上記結果からの推測になるのですが、おそらくIEは処理を軽くするために意図的に2回目以降の縮小処理を省いているのではないでしょうか?

……あくまで推測ですが。

ChromeとFirefoxでは画像が半分まではしましま、半分以下はどのサイズでもグレー1色になりました。

結局のところ対処法は…

元の画像の半分の大きさになるまではきれいに縮小されるので、半分以下の大きさにならないように気を付ける必要がありそうです。

クリッカブルマップがrwdImageMapsで消える|動かなくなる場合がある件

こんにちは、システムの渋谷です。
画像の一部分の領域からリンクを張る、クリッカブルマップという便利な機能があるのですが、レスポンシブで画像のサイズが変わってもリンクの領域は自動的に変わらないため、ブラウザのサイズ変更に応じてリンクの領域をjavascriptで変えてあげる必要があります。

その作業を簡単に行ってくれるResponsive Image Maps jQuery Pluginという著名なjQuery Pluginがあるので、通常これを使ってクリッカブルマップのレスポンシブ対応を実現しています。

使い方も簡単で、「jquery.rwdImageMaps.min.js」を読み込んで

$(‘img[usemap]’).rwdImageMaps();

とするだけでOK!
まったく簡単だ!

と思ってたら、なぜかクリッカブルマップが正常に動いていない案件が……

やせいの バグが とびだしてきた!

症状としては、

  • タブを使って複数のクリッカブルマップを切り替える仕様
  • クリッカブルマップを切り替えるとリンク領域が消えている
  • ブラウザサイズを変更するとなぜか復活する

いろいろ適当にいじってみても正常に動作しないので、泣きながら(というほどでもないですが)ソースを読んでみました。

画像ロード時にimg要素の大きさを取得して、それをもとにレスポンシブで変更された画像の大きさでのリンク領域の計算を行っているようです。

つまり…タブで切り替える仕様などで、rwdImageMaps()実行時にクリッカブルマップが非表示の状態になっていると画像の幅と高さが「0」とされてしまうので、リンク領域も出なくなってしまう、と。

それで解決方法は?

これを解決するには、画像を表示するタイミングでサイズを取得してあげるようにすればいいのですが、プラグインの中身に手を入れると管理が面倒になるので今回は「ブラウザサイズを変更するとなぜか復活する」点に注目して、タブの切り替え時にresizeイベントを発火させることで解決することができました。

コードとしては、タブ切り替え時のslideDown等の関数のコールバックに

function(){$(window).resize();}

を指定してあげればいいだけです。

rwdImageMaps自体が結構長い間メンテナンスされておらず、最新のjQueryで廃止された関数を使っていたりするのでいろいろ書き換えたいところがあるんですけどね。

jQuery 3が来ていますが

Photoshopのアップデートが来て、新機能にテンションが青天井なシステムの渋谷です。
先月開催されたAdobeデジタルフォト&デザインセミナーでは、新機能が「コンテンツに応じた切り抜き」しか紹介されていなかったのですが、それ以外にも細かいところが改善されていて、今回のアップデートはかなり好感触です。

jq

アップデートといえば、今月jQueryの「3」がリリースされていました。
動作が速くなったということで早速新規立ち上げサイトで使ってみたかったのですが、システム部で鈴木さんに相談したところ「初期ロットは不具合が出やすい」ということでもうちょっと枯れるまで待つことになりました。

変更点をかいつまんで

3.x系を入れる準備だけはしておこうということで、とりあえず実験的に2.xで使っていたコードをそのまま動かしたら案の定エラーはいて止まってました。
結構たくさん変更点があるようで、やっぱりこういうのはちゃんと読まないとだめです。

じっくり読んだので、多くのサイトで使っていそうな機能の変更点を2点ほどピックアップしました。

display:noneをhtmlに直接style=”~”の形で書くと.show(),.hide(),.toggle()等で意図した動作にならない

今どきのレスポンシブ対応サイトだとstyle=”display:none”を直接書くようなケースはあまり考えられないのですが、これをインラインで書いてしまうと上書きされず、.show()を使っても表示されないようです。

.load(), .unload(), .error()が削除された

非推奨だったものが削除されたようです。ブラウザからそんな関数知らんと怒られます。
.load()の代わりに.on()を使ってくださいとのこと。

$("#hoge").load(fn);
↓
$("#hoge").on("load", fn);

こんなもの使ってないよー、と思っていたのですが、先人が太古の昔に入れたコードに含まれていました。
文字のサイズを変更してクッキーに保存する機能を標準でいれることが多いのですが、ここでunload()を使って怒られていました。

当面はjQuery2を使っていくものの

新規サイト立ち上げの際は、いつjQuery3に移行しても良いように古いコードは使わないよう書き換えていきたいです。

プログラマのためのthree.jsでの絵作り

03

システムの渋谷です。

three.jsでのモデル描画ができないままだと何か負けた気分だったので、モデル描画サンプルを用意しました。
方言に苦しめられるFBXとかではなく、json形式でデータを書き出したので今回は描画の乱れ等は起きずに済みました。

サンプルはこちら

ステレオカメラが標準で実装されていたので、裸眼立体視にしてみましたが、標準だと画角が小さいせいか効果が弱すぎたのでソース弄って効果を10倍にしています。

サンプルを用意する中で、レンダリング画像が簡単にきれいになるいくつかの抑えておきたい項目を紹介しておきたいと思います。

1.  アンチエイリアス設定

var renderer = new THREE.WebGLRenderer({antialias: true});

レンダラーを初期化するときにantialias: trueを指定しておくと汚いジャギーが消えてくれます。
three.jsのソースを見た限り特に処理の内容が書いていなかったのでブラウザに処理が依存していると思われます。
標準のandroidブラウザでは反映されていませんでした。

2. premultiplied gamma

renderer.gammaInput = true;
renderer.gammaOutput = true;

この2つを指定しておくと光が当たってるところの白とびが抑えられたり、暗すぎるところが明るくなります。

a02

3. HemisphereLight(半球ライト)

lighting

表示したいモデルに当てる光について、屋外を考えた場合

  1. 太陽光
  2. 青空からの環境光
  3. 地面にあたった太陽光の反射

がざっくりあるので、これを用意していきます。

 var directionalLight = new THREE.DirectionalLight(0xfff1d7,0.80);
 directionalLight.position.set(-6, 11, 10);

太陽光は通常の平行光源を使っています。
青空からの青い光と合わせて白になるように若干黄色がかった白を指定しておくといい感じになります。

環境光と地面からの反射は通常はアンビエントライトで我慢するのですが、three.jsではHemisphereLightが用意されているのでこれを使います。

 var hemisphereLight = new THREE.HemisphereLight( 0xd7fbff, 0x7e94a8, 0.7 );
 scene.add( hemisphereLight );

HemisphereLightの第1引数が空の色で、第2引数が地面からの反射の色になります。

反射の色は空の色に合わせたものか、明度を抑えておくと自然な感じに落ち着きます。

a03

というわけである程度見られるレベルにはなったと思うのですが、いかがでしょうか…?

3Dで見せたい商品がある等の場合、写真から3Dモデルが作れる123D Catchmementoなどを組み合わせれば、そう難しくなく実現できそうですよね。

WebGLの時代が来てる(?)

Flash?まぁ…あいつはいいやつだったよ

よくゲーム系の案件をやらせてもらえることの多い渋谷です。

先日、以前Flashで作成した3Dのすごろく(http://ja-dosanko.jp/agri/sugoroku/index.php)をスマホに対応できませんか?という質問をいただいて、ハタと気づいてみればFlashが完全に死んでしまったのでブラウザで3Dをするなら、もうWebGLでやるしかない時代になっていました。

時代が来たと言っても、IE9が未対応でIE11では動作が重いということもあって、最低でもIE9が退場してくれないと「WebGLおすすめです!」と言い出しにくい状況ではありますが。

Internet Explorer 10まで ×
Internet Explorer 11
Microsoft Edge
Google Chrome
Mozilla Firefox
Safari

WebGLで何ができるのか

OpenGL ES 2.0の機能を使ってブラウザに3DCGを描画することができます。
簡単に言うとスマホ用CGとだいたい同じ程度のものを表示できる感じです。

どうやって表示させる?

直でWebGLを叩いてもいいのですが、面倒なコードを山ほど書かなくてはいけないので、そういった作業を簡略化して簡単に3Dを表示してくれるライブラリを使うのが一般的なようです。
有名どころはthree.jsでしょうか?

ちょっとthree.js触って手持ちのモデルを表示させてみます。

three

……ファイルが読み込めないなどのトラブルが多発して、ようやく表示できたのがこれだよ!
法線のフォーマットがおかしくなっているのか正常にライティングが行われてません!

メジャーなファイルフォーマットだと、逆にソフトごとに方言が発生したり、開発元が毎年フォーマットを改定するという所業のせいで、よほど頻繁に更新されるライブラリでないかぎり避けられない問題だったりします。

サンプルプログラムを書き換えるなり、古いフォーマットで書き出し直したりすればうまくいくのかもしれませんが、プログラマは車輪の再開発が大好きなのでパーサーあたりから作りたくなってしまって危険なので泣く泣く諦めます!くやしい!

別の(もっと簡単そうな)方法

最近はやりのゲームを作るためのソフトのいくつかがWebGLに書き出す機能を持っているのでそれに頼りましょう…

代表的なところではUnityUnrealEngineが挙げられますが、渋谷がUnity派のため、ここではUnityでのWebGL制作事例を取り上げたいと思います。

(次回UnityでWebGL編に続く)

Photoshopの簡単な数値変更

はじめまして、近頃WindowsからMacに移行してきてようやく慣れてきた渋谷です。

Coda2を使うためにMacに移ってきたのですが、Photoshop CCのいくつかのバグがMacでは発生しなかったのでほくほくしながら作業しております。

Photoshopは結構長い間使っているのですが、ほかのデザイナーと話をすると私の全く知らない機能を使っていることも多く、いまだに新鮮な発見があります。

 

ということで、今回はあまり使われてなさそうなPhotoshopの小技をば。
数値変更のドロップダウンの隣のアイコンで数値が変更できるというものです。

140522

このアイコンをドラッグで左右に動かそうとすると右の数値が上下するんです!
アイコンだけではなく、数値を入れるドロップダウンボックスの隣の文字(レイヤーの「不透明度」の文字など)にもほぼ実装されているようで、ちょうどいい大きさや不透明度を探るときには重宝しますね。

連続的に数値を変える方法はほかにもありますが、クリックする回数が少なくて済むので便利です。

 

ただ、同じようなインターフェイスを持っているイラストレーターには実装されていないようで、たまに動かそうとして動かないとイラっときます。

イラストレーターだけに。

 

…おあとがよろしいようで。