5

05

2008

WordPress 2.5 のメディア関連のバグ (Bugs)


WordPress 2.5 のメディア関連のバグについて

 

 WordPress 2.5 ではメディア関連の取り扱いが大きく変わりましたが、V2.5.1 に於いてもまだかなりバグが含まれているようです.
 

【バグ1 Bug #1 】

 

 ギャラリーショートコードで表示されるサムネイル画像が、WordPress V2.5よりも前にアップロードされた画像に対しては、サムネイル画像専用の画像データではなくオリジナルの画像データを縮小表示したものとなってしまいます.
 
 WordPress V2.5以降でアップロードした画像データは、きちんとサムネイル用の画像で表示されるのですが、旧バージョンでアップロードした画像データはきちんと処理してくれないようです.ギャラリー表示をした際に、元のオリジナルサイズの画像データで無理矢理サムネイル用の縮小画像を作成することになるので、ギャラリーに含まれる画像の枚数が多いととても思いページになってしまいます.
 

 バグの原因を調べるため、WordPress V2.5 で画像のアップロードデータがどのように処理されているのか確認してみました.検証の結果、画像のメータデータの内容が大分拡張されていました.
 

WordPress 2.3 での画像のメタデータ

a:5:{s:5:"width";i:576;s:6:"height";i:384;s:14:"hwstring_small";s:23:"height='85' width='128'";
s:4:"file";s:63:"/home/y2lab/www/blog/wp-content/uploads/2007/12/converttype.jpg";
s:5:"thumb";s:25:"converttype.thumbnail.jpg";}
 

WordPress 2.5 での画像のメタデータ

a:6:{s:5:"width";i:640;s:6:"height";i:360;s:14:"hwstring_small";s:23:"height='72' width='128'";
s:4:"file";s:80:"/Volumes/Home/WebServer/Documents/testblog/wp-content/uploads/2008/05/ashiyu.jpg";
s:5:"sizes";a:2:{s:9:"thumbnail";a:3:{s:4:"file";s:17:"ashiyu-160x90.jpg";s:5:"width";i:160;s:6:"height";i:90;}
s:6:"medium";a:3:{s:4:"file";s:18:"ashiyu-300x168.jpg";s:5:"width";i:300;s:6:"height";i:168;}}
s:10:"image_meta";a:10:{s:8:"aperture";d:2.79999999999999982236431605997495353221893310546875;
s:6:"credit";s:0:"";s:6:"camera";s:7:"DMC-LX2";s:7:"caption";s:0:"";
s:17:"created_timestamp";i:1174467077;s:9:"copyright";s:0:"";
s:12:"focal_length";d:6.29999999999999982236431605997495353221893310546875;
s:3:"iso";i:100;
s:13:"shutter_speed";d:0.033333333333333332870740406406184774823486804962158203125;
s:5:"title";s:0:"";}}
 

 新しいメタデータの特徴として、サムネイル画像データのファイル名が従来の xxxxx.thumbnail.jpg という形式から、xxxxx-[width]x[height].jpg という形式に変更されたことと、2種類( “thumbnail”, “medium” )のサイズの縮小画像データが用意されていることが分かります.また、元の画像に EXIF データが含まれている場合には、そのデータもメタデータに記録されているのが分かります.
 
 メタデータの中身を少し整形して見やすく表示してみると、各文字の意味がハッキリするでしょう.
 

a:6:{s:5:"width";
     i:640;
     s:6:"height";
     i:360;
     s:14:"hwstring_small";
     s:23:"height='72' width='128'";
     s:4:"file";
     s:80:"/Volumes/Home/WebServer/Documents/testblog/wp-content/uploads/2008/05/ashiyu.jpg";
     s:5:"sizes";
     a:2:{ s:9:"thumbnail";
           a:3:{ s:4:"file";
                 s:17:"ashiyu-160x90.jpg";
                 s:5:"width";
                 i:160;
                 s:6:"height";
                 i:90;
               }
           s:6:"medium";
           a:3:{ s:4:"file";
                 s:18:"ashiyu-300x168.jpg";
                 s:5:"width";
                 i:300;
                 s:6:"height";
                 i:168;
               }
         }
     s:10:"image_meta";
     a:10:{ s:8:"aperture";
            d:2.79999999999999982236431605997495353221893310546875;
            s:6:"credit";
            s:0:"";
            s:6:"camera";
            s:7:"DMC-LX2";
            s:7:"caption";
            s:0:"";
            s:17:"created_timestamp";
            i:1174467077;
            s:9:"copyright";
            s:0:"";
            s:12:"focal_length";
            d:6.29999999999999982236431605997495353221893310546875;
            s:3:"iso";
            i:100;
            s:13:"shutter_speed";
            d:0.033333333333333332870740406406184774823486804962158203125;
            s:5:"title";
            s:0:"";
          }
  }
 

どうやら a:6 は要素が6個の配列、s:数字 は文字列を表す記号でその後の数字は文字数、i は整数、d は実数ということでしょう.キーの名前とその値で1組の要素となっているようです.
 

 

 このようにメタデータの内容が大きく拡張され、サムネイル画像のメタデータが変わったので、新しい WordPressが旧タイプのメタデータの処理を行わなくなったのが原因だと思いましたが、WordPress のコードを眺めていたら、きちんと旧バージョンのサムネイル画像のデータも取り扱えるようにコードが書かれていました.ただ、この旧バージョンのサムネイル画像のデータを扱う部分にバグがあり、そのため旧画像データのサムネイルがきちんと扱えない事が判明しました.
 


“media.php” の function image_downsize() のバグの修正

 

 wp-include ディレクトリの下にある、ファイル “media.php”の最初の方(55行目付近)にある、function image_downsize($id, $size = ‘medium’) が、目的の画像データのサムネイル画像のURLと画像サイズを取得する部分です.
 

	elseif ( $size == 'thumbnail' ) {
		// fall back to the old thumbnail
		if ( $thumb_file = wp_get_attachment_thumb_file() && $info = getimagesize($thumb_file) ) {
			$img_url = str_replace(basename($img_url), basename($thumb_file), $img_url);
			$width = $info[0];
			$height = $info[1];
		}
	}
 

 この関数の 74行目以下の部分が旧バージョンの画像データのサムネイルを取り出す部分です.wp_get_attachment_thumb_file() という関数の実引数が空になっていますが、これでは正しく対象とするアタッチメント画像のデータを取り出すことができません.正しくは wp_get_attachment_thumb_file($id) ですね.
 
 更に、 if 分のステートメントの書き方が問題です.PHPの式の評価順序は調べないと良く分かりませんが、$thumb_file = wp_get_attachment_thumb_file() という式は、if 文の前で評価しておいた方が良いでしょう.
【 優先順位は 代入演算子(=) > 論理演算子(&&) で、 && は左結合なので問題ない筈ですが、念のためハッキリと順序立てておきます 】
 
 従って、この部分は次のように修正しておきましょう.
 

	elseif ( $size == 'thumbnail' ) {
		// fall back to the old thumbnail
                $thumb_file = wp_get_attachment_thumb_file($id);
		if (  $info = getimagesize($thumb_file) ) {
			$img_url = str_replace(basename($img_url), basename($thumb_file), $img_url);
			$width = $info[0];
			$height = $info[1];
		}
	}
 

【バグ2 Bug #2 】

 

 モノクローム画像データをアップロードすると、サムネイル画像が作成されず、メタデータの内容もファイル名しか記述されない.
 
 まだ原因をつきとめていませんが、モノクローム画像データ(JPEG)をアップロードして、標準的なギャラリーで表示してみると次のようになります.モノクロ画像のサムネイル画像が作成されず、正確な画像サイズも取得できないのでおかしな表示になります.
 


標準的な[gallery]でメタデータが含まれない画像を表示した場合

 


 

 


追記:モノクローム画像データを正しく処理できない件

 

 Wordpressがモノクローム画像データをハンドリングできないというバグの件ですが、どうやらバグではなくWordpressがモノクロ画像データを取り扱わない仕様になっている事が判明しました.アップロードだけしておいて、表示だけおかしな結果になるというのも困りものですね.
 
 画像データの種類に応じて対応する画像かどうか判定している部分は、wp-admin/includes/image.php の function file_is_displayable_image() です.
  
 コメントには一部の WEBブラウザが モノクロと CMYK JPEG画像を表示できないので不適正として処理しているようです.
  
 私が試したWEBブラウザ( Mac OS X: Safari3.1, FireFox2, FireFox3, Opera 9.5 WinXP: IE6, IE7, IE8, FireFox2, FireFox3, Safari3.1, Opera9.27 )では、モノクロJPEG画像はどのブラウザでも表示できました.
CMYK JPEG画像については、 IE6, IE7, IE8 と FireFox2 では表示できませんでしたが、それ以外のブラウザでは表示できます.CMYK JPEG 画像の場合のみ対象から外せば OK でしょう.
 

// is the file an image suitable for displaying within a web page?
function file_is_displayable_image($path) {
	$info = @getimagesize($path);
	if ( empty($info) )
		$result = false;
	elseif ( !in_array($info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG)) )
		// only gif, jpeg and png images can reliably be displayed
		$result = false;
	elseif ( $info['channels'] > 0 && $info['channels'] != 3 ) {
		// some web browsers can't display cmyk or grayscale jpegs
		$result = false;
	}
	else
		$result = true;
	return apply_filters('file_is_displayable_image', $result, $path);
}

オリジナルソースコード ( original source code : wp-admin/includes/image.php )

   
// is the file an image suitable for displaying within a web page?
function file_is_displayable_image($path) {
	$info = @getimagesize($path);
	if ( empty($info) )
		$result = false;
	elseif ( !in_array($info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG)) )
		// only gif, jpeg and png images can reliably be displayed
		$result = false;
	//elseif ( $info['channels'] > 0 && $info['channels'] != 3 ) {
	elseif ( $info['channels'] > 3 ) {
		// some web browsers can't display cmyk or grayscale jpegs
		$result = false;
	}
	else
		$result = true;
	return apply_filters('file_is_displayable_image', $result, $path);
}

CMYK 画像だけを除外するように修正 ( modified source code )

 

 既にアップロードしてしまったモノクロ画像には正しいメタ情報が含まれていませんので、上記の修正を加えた後で再度アップロードし直して下さい.
 


標準的な[gallery]で表示 (修正後)