今回は、WordPressテーマで高解像度ディスプレイに対応した画像を出力する方法について取り上げます。

目次

  1. Retinaディスプレイで画像をくっきり表示する方法
  2. 高解像度画像を投稿に挿入する

 

Retinaディスプレイで画像をくっきり表示する方法

縦横が2倍解像度の画像を用意する

WPに限らず一般的なコトですが、iPhoneなどの高解像度ディスプレイ(以下、Retinaディスプレイとします)でサイトを見ると、画像がぼやけて見えることがありますよね。Retinaディスプレイは縦横それぞれ従来の2倍の解像度となっているため、画像をクッキリ表示させるためには、縦横それぞれ倍解像度以上にした画像を用意する必要があります。

縦横が2倍のサイズの画像が必要!

1x_pattern 2x_pattern

imgタグで画像を挿入する場合

倍解像度の画像をsrcに指定して、widthとheightは画像サイズの1/2を指定する

背景画像として表示する場合

-webkit-image-setで通常解像度画像と高解像度画像の2つをそれぞれ指定する

 

WordPressで高解像度画像を出力する方法

次は、これらをWordPress上でどう実現するかを考えます。話の都合上、WordPressで扱う画像の表示方法を次の4つに分類します。

  1. 投稿に挿入する画像
  2. アイキャッチ画像
  3. 背景画像
  4. メディアページに表示する画像

この中で対応が難しいのは#1の投稿に挿入する画像です。通常、投稿中に画像を挿入する場合は、投稿編集フォームの左上にある「メディアを追加ボタン」を押して画像を選択しますよね。しかしこの方法だと、画像サイズがそのままimgタグのwidthとheightに反映されてしまうので、画像がぼやけてしまいます。そこで本記事では、#1に対応する方法について紹介します。

 

メモ:
#2と#4は、後日別の記事で紹介しようと思います
#3は、_2x画像をuploadしてstyle.cssを書き換えるだけなので割愛します

 

 

高解像度画像を投稿に挿入する

メディアライブラリの画像サイズメニューをカスタマイズする

WordPressでimgタグのwidthとheightを1/2にする手段は色々考えられますが、この記事では次のように、画像サイズリストの中に高解像度画像挿入用メニューを作ってみます。

MediaUploader

今回のカスタマイズでは、高解像度画像・・・というサイズが選択された場合は、本来の画像ファイルのwidthとheightの値を1/2にしてからimgタグを投稿に埋め込むように処理を書き換えます。

 

カスタマイズの概要

高解像度画像用のサイズが選択されたらwidthとheightを1/2にする処理を実現するために、以下の4点を実装していきます。

  • 新しい画像サイズを追加する
  • メディアライブラリのサイズ選択時に作成した画像サイズのメニューが表示されるようにする
  • メディアライブラリのサイズ選択時のメニューのラベルを修正する
  • 作成した画像サイズが選択された場合は、widthとheightの値を1/2にする

これらは全てfunctions.phpに実装します。

functions.php

ソース全文はココ(on github)にあります。

2014.5.26 L71のコードミスを修正しました。

2014.8.22 フルサイズの高解像度モードを追加しました。

続いて、ソースコードの説明をしますね。

 

新しい画像サイズを追加する

次の関数を使って、新しい画像サイズをWordPressに追加登録します。

add_image_size($slug, $width, $height, $crop)

ここでは、高解像度用サムネイルを300px、中サイズを600px、大サイズを1200pxとして設定しています。実際はRetina Displayで1:1解像度で出力できるようにするためにwidthとheightの値を1/2に指定するので、表示上の画像サイズはそれぞれ150px、300px、600pxとなります。

 

メディアライブラリで画像選択時に新しい画像サイズを選択可能にする

フィルタを使って、先ほど追加した3つの画像サイズを選択できるようにします。/wp-includes/media.phpに実装されているフィルター’my_custom_image_sizes’は、フィルター関数に対して次のような配列を渡してきます。

array_sizes

これらはデフォルトで用意されている画像サイズです。フィルター関数my_custom_image_sizesは、この配列にadd_image_sizesで追加した画像サイズの要素をmergeしてreturnしています。

 

メディアライブラリのサイズ選択時のメニューのラベルを修正する

画像サイズ選択メニューのラベルは「画像サイズ名 width x height」の形式で表示されます。このラベルのwidthとheightがそれぞれ元の1/2の値になるようにカスタマイズします。

sizes_menu

メディアライブラリのポップアップを表示するjavascriptに渡す変数に対するフィルターが ‘wp_prepare_attachment_for_js’です。このフィルターから受け取れる引数は、次のような配列です。なお、処理中の画像のフルサイズは900x1200pxです。

 

array_response

多くの要素がありますが、ここで利用するのは$response[‘sizes’]です。$response[‘sizes’]も配列で、画像のwidth, height, 画像ファイルへのURL、縦長or横長の値が格納されています。フィルター関数add_imagesize_for_js_preparationは、配列$response[‘sizes’]のうちadd_image_sizesで追加した画像サイズに対してのみwidthとheightの値を1/2に書き換えています。

 

foreach ($response['sizes'] as $size => $values) {
	if( in_array($size, array('thumbnail_for_2x','medium_for_2x','large_for_2x','full_for_2x')) ) {
		$response['sizes'][$size]['width'] = floor($response['sizes'][$size]['width'] / 2);
		$response['sizes'][$size]['height'] = floor($response['sizes'][$size]['height'] / 2);
	}
}

ところで上図にある$response[‘sizes’]配列には、’large_for_2x’の要素がありません。上の図例で処理中の画像ファイルが’large_for_2x’と’full’のサイズが重複するので、このフィルターの前段の処理で’large_for_2x’が削除されています。そこで次のように、画像のフルサイズ==large_for_2xのサイズとなる場合は、large_for_2x要素を追加する処理を入れています。また、medium_for_2x, thumbnail_for_2xの場合も同様にしています。

 

$full_max = max($response['sizes']['full']['width'], $response['sizes']['full']['height']);
$key = '';
switch ($full_max) {
	case 300:
		$key = 'thumbnail_for_2x';
		break;
	case 600:
		$key = 'medium_for_2x';
		break;
	case 1200:
		$key = 'large_for_2x';
		break;
	default:
                $key = 'full_for_2x';
}
$response['sizes'] = array_merge($response['sizes'], array($key => array(
		'width' =>  floor($response['sizes']['full']['width'] / 2),
		'height' => floor($response['sizes']['full']['height'] / 2),
		'url' => $response['sizes']['full']['url'],
		'orientation' => $response['sizes']['full']['orientation'],
)));

ここまでのカスタマイズで、メディアライブラリから画像挿入するときに、フルサイズ以下全ての画像サイズについて選択メニューが表示される状態になりました。

 

高解像度画像用サイズが選択された場合は、widthとheightの値を1/2にする

投稿に画像を挿入するときにadd_image_sizesで追加した高解像度画像用サイズが選択されたら、imgタグのwidthとheightを1/2にしてから出力する処理を追加します。ここでは、フィルター’get_image_tag’を使います。

 

つぶやき:
get_image_tagは、フィルタリング対象が、<img src=”…のようなimgタグの文字列そのものです。本当はimgタグを出力する前のwidthとheightの値を直接操作できるフィルター等があれば良いのですが見当たりませんでした。他にもっといい方法があるかもしれません。また、将来もっとよいカスタマイズができるようになるかもしれません。

 

フィルター’get_image_tag’からは、imgタグ文字列を受け取ることが出来ます。そこでフィルター関数change_imagesize_tohalfでは、imgタグ文字列から正規表現でwidthとheightの値を取り出して、それぞれ1/2にしてからimgタグ文字列を再生成します。なお、1/2にする処理は、高解像度画像用サイズが選択された場合にのみ行うよう実装します。

以上で、カスタマイズ終了です。まとめると、

  • add_image_sizesで、高解像度画像用サイズを作成
  • image_size_names_chooseフィルターで、カスタム画像サイズをメニューに追加
  • wp_prepare_attachment_for_jsフィルターで、画像サイズメニューのラベルを修正
  • get_image_tagフィルターで、widthとheightの値を1/2に修正

という流れになります。

 

最後に

今回は、投稿に画像挿入するときに、imgタグのwidthとheightを1/2にするモードを追加する機能を実装することで、RetinaDisplay対応としました。他にも色々代替手段は考えられます。

  • 投稿に2倍サイズの画像を挿入した後で、手書きでwidthとheightを1/2に修正する。
  • 上をjavascriptで実装する
  • get_image_tagフィルター関数のみを実装し、全ての画像に対してwidthとheightを1/2にする処理とする
  • メディアにタクソノミーを追加して、各画像に対して高解像度or notを分類し、get_image_tagフィルターでwidth&heightを修正する

もっとこういう方法がいいよーという案がありましたら、Twitterとかで話しかけてくださると嬉しいです!それでは、今回はこの辺で〜

 

「実践的テーマの作成」の記事