【IE10・11対応】svgを使って画像をグレースケール化する
こんばんは、発芽米ぱんだです。
最近svgがマイトレンドです。
IE(Internet Explorer)でもsvgが対応したこともあって、また高解像度のディスプレイが増えてきたこともあって、Webページにsvgが使われることは増えてきている気がします。
単純に案件で使うことが多いのもありますが、個人的にWeb上でのアニメーションに興味があるので、何かと習得したい欲が高い分野であります。
Scalable Vector Graphics(スケーラブル・ベクター・グラフィックス、SVG)は、XMLベースの、2次元ベクターイメージ用の画像形式の1つである。アニメーションやユーザインタラクションもサポートしている。SVGの仕様はW3Cによって開発され、オープン標準として勧告されている。
簡単に言えば、HTMLのように書ける、全然ボケない画像っていうことです(雑
詳しくはググってください!
さて表題の件ですが、svgは色々と汎用性が高く、カラー画像の上にsvgのフィルタを載せるだけで、カラー画像をモノクロ(グレースケール)化することもできたりします。
今回は、そのグレースケール化の方法に関して書こうと思います。カラー画像とモノクロ画像を出し分けしたい時などに、使えると思います。
ーーー
さっきからsvgの話をしておりますが、
最近のCSSは優秀で、CSSだけでも画像をグレースケール化することは可能です。
例えば、以下。
メイドラゴン終わっちゃったなぁ・・・ってのは脱線するのでよしますが、
この画像に以下のようなCSSを適用すると、
img{
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-o-filter: grayscale(100%);
-ms-filter: grayscale(100%);
filter: grayscale(100%);
}
グレースケール化します。
ただ、IEでご覧になっている方は、グレースケール化していないはずです。
IE対策で、少し前までは以下のようにfilterプロパティを記述するだけで解決していました。
img{
filter: progid:DXImageTransform.Microsoft.BasicImage(GrayScale=1)
}
しかし、悲しきかな・・・DXフィルターはIE10から対応しなくなってしまいました。(参考URL:DX フィルターがサポートされなくなった (Windows))
IE10からCSS3によるfilterを標準準拠するようにしたので、IE9まで使えていたDXフィルターをなくしたようです。
「お、じゃあCSSだけでグレースケールできるね!」・・・しかしそうはさせてくれないのがIEさんです。
先ほどの参考URLのページによれば、DXフィルターを廃止した代わりにCSSで実装できるのは、
・Alpha(透明度)
・AlphaImageLoader(透過のpng)
・Gradient(グラデーション)
・DropShadow(ドロップシャドウ)
・Matrix(3D変形)
だそうです。
IEのfilterプロパティについてはこちら(filter-スタイルシートリファレンス)をご参照ください。
ここまで来ると、IEでもグレースケールを表現する為には、JavaScript、もしくはsvgを使うしかなくなってきます。(え、Photoshop?どうぞご自由に・・・)
JavaScriptを使うのも勿論アリなのですが、例えば一枚の画像をグレースケール化する為だけにJavaScriptを使うなんてことは・・・解せぬ。非常に解せぬ。(個人的な心象なので、JavaScriptで解決したい方は別のページへどうぞ)
さて、ようやく出番が来ましたsvg。
最初に答え(あくまで一例)を書いてしまいますが、以下のように記述すると、IEでもちゃんとグレースケール化してくれます。HTML内に直接記述する、インラインsvgを使います。
【HTML】
<svg xmlns="http://www.w3.org/2000/svg" class="grayscale_svg" width="100%" height="400" version="1.1">
<defs>
<filter id="grayscale">
<fecolormatrix type="matrix" values="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"></fecolormatrix>
</filter>
</defs>
<image x="0" y="0" width="300" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://cdn-ak.f.st-hatena.com/images/fotolife/h/htgmi/20170418/20170418002633.jpg">
</svg>
【CSS】
image {
filter: url(#grayscale);
}
CSSの「url(#grayscale)」でHTMLのsvgタグ内の「id="grayscale"」箇所を呼び出しています。
hover時にグレースケールを解除したい場合などは、hover時にfilterプロパティを無効化すれば大丈夫です。
まるっとコピーして使いたい方は以下からどうぞ。
ただ、画像自体もsvgタグの中に記述せねばならず、svg独特の記述に則る必要がある(imgタグではなくimageタグにするなど)ので、少々使い勝手が悪いです。他にもっと良い方法があれば、追記したいと思います。
注意点として、svgタグでwidthとheightの指定を忘れずに!あと、imageのx, yの座標を指定しないといけないのも意外と盲点ですかね。このあたりもsvg特有ですね。
CSSのfilterプロパティで、CSSファイルと同ディレクトリに置いたグレースケールのsvgを呼び出したりもしてみたのですが、結局はIE10〜ではインラインsvgでしかうまく行きませんでした。出来たよ、って方がいらっしゃったら是非教えてください。。
もっとsvgとは仲良くなりたいですね!
それでは、また!
マークアップをする時に僕が気を付けていること
こんばんは、発芽米ぱんだです。
先日は数学について書きましたが、今回は、肝心要の、マークアップについて書きます(本職なので)。
と言っても、具体的なノウハウの共有ではなく、普段マークアップするにあたって、どういった心構えでいるべきかという、殆ど自分向けの内容となっております。
目指すゴールが鮮明になればなるほど、そのゴールに辿り着くまでのプロセスも明確になります。ご参考になれば幸いです。というわけで、いざ。
ーーー
■HTML
HTMLの書き方は千差万別ですが、やはり流行り廃りというものはございます(なんか落語の前座みたいな始め方)。
他の技術と同様、HTMLも日々進化しているので、いつまでも古い記法に則った書き方をしていると、そのうちブーメランを喰らいます。クライアントにも迷惑をかけてしまいます。
そんなこんなで、HTMLコーディングの際に僕がいつも意識していること(目標のようなもの)は以下になります。
(1) バックエンドの言語(Ruby, Ruby on Rails, PHPなど)が絡んでも破綻(※1)しないようにする
(2) 修正が発生しても、既存のコードに手直しする必要がないようにする
(3) W3Cの勧告内容に基づいているかどうか
(4) 上記を、スピーディに確実にこなす(余裕ができたらHTMLテンプレートエンジンを使いこなせるように)
現段階では上の4つになりますが、他にあれば、また追記致します。
(※1)「破綻」とは以下のようなことを想定しています。
・要素を追加、削除した際に、レイアウト等が崩れ、手直しが必要になってしまう
・タグの種類を替えた際に、手直しが必要になってしまう
これらが出来るようになれば、いっぱしのコーダーであるとは思います。が、僕はまだまだ出来ていません。出来るようになる為には、どうしたら良いでしょうか。
僕が日々行っている(つもりである)ことは以下です。
・他人のコードをよく見て学ぶ(これが何かと手っ取り早い気はする)
・最新のHTMLに関する情報を常にキャッチする
・基礎的な知識が疎かになっていないか、教本を読んだりして自己チェックを行う
「他人のコードをよく見て学ぶ」、これが一番、目指すべきものが具体的にハッキリしてモチベーションも保ちやすいですが、他人様のコードが全て正しいとは限らないので、自分で調べる姿勢は必要だと思います。
これらを毎日実践でき、そして周りに共有できたら、理想ですね(主に自分に言っている)。
■CSS
最近はCSSでのアニメーションも主流となり、何かと目新しいことに目が向きがちですが、やはり基礎は大事だと思います。
僕がCSSの記述で目標にしていること。
(1) 各ブラウザに依存しない見た目を作る
(2) 他人が手を加えやすいclassの命名、プロパティの設定(無駄に打ち消したりしない)
(3) W3Cの勧告内容に基づいているかどうか
(4) 上記を、スピーディに確実にこなす(Sassなどを使いこなす)
上を踏まえて、僕がCSSの記述で気を付けていることは以下です。
・各ブラウザの各プロパティの対応状況を注視しておく(アップデート情報など、最新情報は常にキャッチ)
・各ブラウザのレンダリングの特徴を踏まえておく
・classのネーミングをルールに基づいて行う(現在の主流ではBEMか)
・各プロパティの書く順番を、おおよそで良いので統一する(最初にwidth, heightを書くなど)
・共通化できるところは共通化して無駄を省く(打ち消しや「!important」を最大限なくす)
いつも使っているメインブラウザだけでコーディングをしていると、他のブラウザで見た時の表示の違いにゲンナリすることが多々あります。そういうことが起きない為にも、各ブラウザのレンダリングの特徴を踏まえることは大事です。が、根本から理解することは結構ハードなので、おいおい共有できればと…(逃げ)
ーーー
長々と書きましたが、要は「日々勉強」です。(ざっくばらん
今まで僕はほとんど独学でマークアップを学んできましたが、今現在大変なしっぺ返しを食らっているので、皆さんはそうならぬよう…(独学と言っても、きちんと体系化できていれば、何も問題はありません)
さぁ、月曜日。また明日から頑張っていきましょう。
それでは、また!
新米文系エンジニアのための数学のすゝめ
ーーー
■この記事の要旨
・新米エンジニアは、日々の業務(今回はコーディング、プログラミング)でわからない箇所をわからないまま考えて行っていては時間の無駄(考えることが悪いわけではないので誤解なきよう!)
・効率的な思考プロセスを得るために、数学はうってつけ
ーーー
ブログはじめました。
最初は数学についてです。え、数学?そう、数学です。あ、ちょっと待って、少しでも読ん(ry
マークアップエンジニア、フロントエンドエンジニア、サーバサイドエンジニア…世界中の多くのエンジニアが、業務内容は違えど、日々あらゆる問題(マイナスな意味だけでなく)に立ち向かっていることと思います。
しかし、僕のようにWebの世界に飛び込んで数年のペーペーエンジニアは、往々にして業務が非効率になりがちで、しかも間違いに気付かずに突き進んでいる、なんてことも…あり…(超冷や汗)
特に僕のように文系出身のエンジニアさんは、感覚で前に進んでしまう恐ろしさを、よくご存知なのではないかと思います。
「まぁでも、なんとかなってるし、作ったものも一応ちゃんと動いているし?」わかります。ものすごくわかりますその気持ち。僕もずっとその気持ちでした。
でも、新米エンジニアが感覚で業務をこなすのは、色んな意味でかなりリスキーです。
文系出身ペーペーがわかったようなことを言ってめちゃくちゃ恐縮なのですが、理系出身の皆さんは、割と論理的な考え方が得意なのではないかと思います。
コンピュータは全て論理の上で動くので、論理的に考えられて作られたスマーーートなコードは、コンピュータに優しく、他の人が見てもわかりやすく、無駄がなく、破綻しづらいです。そしておそらく、とても効率的に作られているはずです。
そう、僕が作るような継ぎ接ぎだらけのコードは、コンピュータにいらぬ負担をかけ、他の人が見ても意味不明で、無駄だらけで…(言ってて辛くなってきた)
文理を問わずとも、ベテランと新米の一番の大きな差は、経験ではないかと僕は思います。つまり、こなしてきた数が全然違う。業務を行う上で見ているもの、考えていることが全然違うということです。
じゃあ経験のない感覚派新米文系エンジニアはどうすればいいのか。
何とかしなければいけません。
「教えてもらえばいいや〜」では、いつまでも足手まといのままです。
前座がかなり長くなりましたが、そんな時、僕がオススメするのが数学です。つまり、思考の訓練として、数学を使うということです。
経験が無いのは当たり前。じゃあせめて、うまく業務をこなしていくための、ある程度のノウハウぐらいは身につけましょう。
Web業界に飛び込んで早2年の僕が感じている数学の魅力。それが少しでも皆さんに伝わればいいなと思います。
ーーーーー
さて皆さん、いきなりですが問題です。数学の問題です。
$l ≦ m ≦ n$ であって、 [ rac{1}{l} + rac{1}{m} + rac{1}{n} = rac{3}{2} ]を満たす自然数の組$(l, m, n)$をすべて導きなさい。(2004年明治薬科大)
ちなみに、自然数とは、1から始まる、正の整数のことです。0は今回は含みません。マイナスの数字は自然数ではありませんのでご注意を。
是非、今回だけでも良いので、実際に解いてみてください。特に新米文系エンジニアの皆さんには、ググらず、正解が出るまで、ねばってみていただきたい!
結構頭の体操になりますよ。
解いてくださってる方は、時間も測ってみてください。あ、でも決して早く解いてくださいということではありません、じっくり解いてみてください。
・・・・・・
いかがでしょうか。
僕はこの問題を解くのに1時間もかかりました(こんな記事を書いておきながら、数学の問題を解くのは超久しぶりです、てへぺろっ)
僕がどういう思考回路でこの問題を解いていったか、小馬鹿にしながらご覧ください。
(1)分数のままだと気持ち悪いので、綺麗な式に直す
(2)変数が3つもあるのが気持ち悪いので、変数$ l $を1から代入していく
(3)変数$ l $を1から3ぐらいまで代入していって、今度は100ぐらいの極端な数字を代入して、それぞれ得られた$ m $と$ n $の式に規則性がないか見出そうとする
(4)$ m $と$ n $だけになってもごちゃごちゃなので、αとβに置き換える
…以下略
アホです。自ら蟻地獄にハマっています。
これが実際の業務であったとしたら、正解を導き出せたから多少は良いものの、非効率極まりないです、はい。すみませんでした。
解答が知りたい方は、以下のURLの「整数問題」の2番目を。うわっ、こんなやり方があったか〜!ってなるかもしれません(笑)
じっくり時間をかけて考えてくださった方ほど、「整数問題」の3番目が瞬殺であることに、きっと感動してくれるはずです。
果たして、僕は何がいけなかったのでしょうか?
この問題においてですが、まず一番に、条件式(不等式など)を導き出すことに主眼を置くべきだった、と思います。
「すべて導きなさい」と問題にあることから解答が複数あることが考えられるので、条件式を導く出すことは、必須と言って過言ではありません。
たった数行、しかしヒントは全て問題の中に隠されています。
しかし、知識・経験が無いと、こうも、がむしゃらに一つ一つ数字を代入しようとしてしまうのか…(答えが百個もあったらどうするつもりなのか)
プロセスさえわかってしまえば、驚くほど効率化できるものなんです。
これって、意外とコーディング・プログラミングに共通すると思います。
最初のうちは、経験がないので、わからなかったり時間がかかっても当然です。
また、仮に、ある程度の知識はあったとしても、知識はあくまでもツールの一つなので、うまく使いこなせなければ意味がありません(例えば数学なら、いくら公式を丸暗記しても、解けない問題ってたくさんありますよね)。
難しい数学の問題を解いている時は、難しい仕様を実装しようとしている時に似ていると思います。私だけでしょうか。ど〜でもい〜ですよ〜(これわかる人はきっと同世代)
数学楽しい〜〜〜!!!
それではまた!
ちなみに、問題の答え。
$(l, m, n) = (1, 3, 6), (1, 4, 4), (2, 2, 2)$
最後のまとめ:この記事は、新米文系プログラマが全員数学を勉強しなければいけないと言っている訳ではないです。日々の業務をこなす為のヒントが、数学に隠されているよ、というのが僕の言いたいことです。念のため。