WordPressの記事内に画像を挿入すると、ボヤケてハッキリしなくなります。画像をアップロードしたタイミングでシャープに加工する、という処理をfunctions.phpに追加すれば、問題は解決します。
ソースコード
functions.phpに書くソースコードは下記です。
function custom_image_upload_filter( $metadata, $attachment_id ) {
// アップロード保存先のディレクトリ
$upload_dir = wp_upload_dir();
// シャープの設定値
$sharpen_matrix = array(
array(-1, -1, -1),
array(-1, 16, -1),
array(-1, -1, -1),
);
$divisor = array_sum( array_map( 'array_sum', $sharpen_matrix ) );
// シャープを掛けるファイルタイプ
$allow_mime_type = array(
'image/jpeg',
);
// アップロードファイルのフルパスを取得
$attached_file_path = get_attached_file( $attachment_id );
// MIMEタイプを取得
$finfo = new finfo();
$attached_mimetype = $finfo->file( $attached_file_path, FILEINFO_MIME_TYPE );
// ファイルタイプの判別
if( in_array( $attached_mimetype, $allow_mime_type ) ){
// サイズのバリエーション全てが対象とする
foreach( $metadata['sizes'] as $key ){
// 画像ファイルのフルパス
$img_path = $upload_dir['path'] . '/' . $key['file'];
// 画像のオブジェクト的なものを生成します。
$im = @imagecreatefromjpeg( $img_path );
// シャープの処理
imageconvolution( $im, $sharpen_matrix, $divisor, 0 );
// jpg画像として保存
imagejpeg( $im, $img_path );
// 画像のオブジェクト的なものを破棄します。
imagedestroy( $im );
}
}
return $metadata;
}
add_filter( 'wp_generate_attachment_metadata', 'custom_image_upload_filter', 10, 2 );
ソースコードの解説
自動的にシャープを掛ける為に、やっていることは下記です。
- wp_generate_attachment_metadataフックで、ファイルアップロード時に動作させる。
- wp_upload_dir()でアップロードディレクトリを取得する。
- jpg画像のみ(image/jpeg)を対象とする。
- 各縮小サイズがある限り($metadata[‘sizes’])をforeachで回す。
- imagecreatefromjpegでJPG画像にする。
- imageconvolutionで画像をシャープに加工する。
- imagejpegで、画像をディレクトリに保存する。
- imagedestroyで画像を解放する。
最初に、wp_get_image_editor()を使うべきかと悩んだのですが、シャープにするメソッドが無いので却下しました。
シャープのソースを入れても、さらにボヤケてしまう場合
上記のソースを使うと、メディア設定の縮小画像に対して、シャープが掛かります。でも、これだけだと、シャープにならずに変わらずボヤケてしまう場合があります。正確には、シャープは掛かっているんだけれども、ブログで表示の仕方に問題がある場合です。
ボヤケてしまう理由は下記のいずれかです。
- widthやheight属性値が実際の大きさと違う
- CSSでimgタグにpaddingやmarginとともに、box-sizing: border-box;が指定されている
- WordPressテーマ特有の仕組みが入っている
それぞれの解決方法を以下に書きます。3に関しては、このブログで使用している賢威8の方法のみになります。
1.widthやheight属性値が実際の大きさと違う
例えば、700サイズの画像を500で表示した比較です。
widthを700に設定
widthを500に設定
属性値のwidthやheightで縮小させないためには、属性値そのものを削除するか、画像の大きさとピッタリ同じ属性値を設定すると良いです。WordPressのテーマによって属性値の設定は変わることがあります。
私は、メディア設定の中サイズに対して、700を設定しています。属性値の削除はしておりません。もしwidthとheightを削除したい場合は、functions.phpに下記を書いてください。
add_filter( 'post_thumbnail_html', 'remove_width_attribute', 10 );
add_filter( 'image_send_to_editor', 'remove_width_attribute', 10 );
function remove_width_attribute( $html ) {
$html = preg_replace( '/(width|height)="\d*"\s/', "", $html );
return $html;
}
2.CSSでimgタグにpaddingやmarginとともに、box-sizing: border-box;が指定されている
画像へ額縁のように隙間を空けて枠線を引いている場合、box-sizing: border-box;が指定されていると、自動で縮小され画像がボヤケます。このブログでも枠線を引いています。
テーマの仕様としてbox-sizing: border-box;が指定されているので、box-sizing: content-box;でボヤケないように指定をしています。これで枠線を書いても大丈夫です。
3.WordPressテーマ特有の仕組みが入っている
私が このブログで使用している賢威8に限定した解決方法になります。
賢威8は、画像のクラスに wp-image-xx が入っていると、srcsetが自動で挿入されて、画像がボヤケます。賢威8を使っている場合に限り、クラスからwp-image-xx を消す処理を入れると解決します。
add_filter('get_image_tag_class', 'custom_image_tag_class', 10, 4 );
function custom_image_tag_class( $class, $id, $align, $size ){
// 初期値 'align' . esc_attr( $align ) . ' size-' . esc_attr( $size ) . ' wp-image-' . $id
return 'align' . esc_attr( $align ) . ' size-' . esc_attr( $size );
}
クラス有り
クラス無し
シャープの比較画像
シャープの違いは、こんな感じです。上がシャープ加工前、下がシャープ加工後です。画像の大きさは、メディア設定の中サイズを700にしています。
imageconvolutionシャープ前
imageconvolutionシャープ後
サムネイル150×150での比較。
シャープ前
シャープ後
phpで、画像をシャープにする方法はimagefilter()を使い、引数にIMG_FILTER_MEAN_REMOVALを使う方法があります。私は選びませんでした。なぜなら、画像が荒くなりすぎてしまう為です。下記に比較画像を置いておきます。
上がIMG_FILTER_MEAN_REMOVAL加工前、下がIMG_FILTER_MEAN_REMOVAL加工後です。
imageconvolutionを使うにあたって、どのようにシャープの微調整をするか、です。たたみ込み演算というらしいのですが、私にはサッパリ判りません。convolutionの和訳が、たたみ込み演算です。
上記のプログラムにおいて、どうやら、真ん中の数値を変えると、シャープの強さが変わるようです。数値を小さくすると強くなり、大きくすると弱くなる。
$sharpen_matrixの真ん中の16を9に変えて、比較してみます。
真ん中の16を32に変えた例です。
うーん、真ん中の数値が16が、1番シャープらしいと感じます。
ということで、Wordpressにアップロードした画像において、縮小画像をシャープにしたければ、imageconvolutionで真ん中の数値は16にしましょう!