iPhone で撮影した画像ですが、iOS 上の Safari や、facebook のリンクのプレビュー画面で意図した向きで表示されない件が気になっていたので、対策を考えてみました。
原因は、撮影した向きでは画像が保存されず、向きを補正する情報が保存されることに起因すると推定しているのですが、対策からすれば、向きを補正する情報を読み取り、正しい向きでシンプルがデータとして再構成すれば良い、ということになるかと思うわけです。
不用な Exif データなども削除すれば、多少なりともトラフィクの軽減にもなるわけですし、そういう部分も掘り下げたいところではあるんですが、それ以前に、iPhone で撮影する場合、画素数の調整なんかができない気がするので、アホのように巨大な画像ファイルになるので、それを手当しなければならず、現状は、Wordpress のプラグインで、imsanity というものを使って対策をしているのですが、これ自体は、リサイズしかしてくれないので、たたき台にするにしても、もっとマシなものがあるだろう、ということで探してみました。
そうしたところ、fix image rotation というものがあり、早速落としてみました。
動作的には、filter_wp_handle_upload_prefilter で、ファイルアップロード時にフックして、実処理は、fixImageOrientation でやっているわけですが、ここでは、WP_Image_Editor インスタンスが実際のイメージ処理を行っています。
調べてみたところ、あまり詳しいマニュアルはなかったのですが、
$image = wp_get_image_editor( 'cool_image.jpg' );
if ( ! is_wp_error( $image ) ) {
$image->rotate( 90 );
$image->resize( 300, 300, true );
$image->save( 'new_image.jpg' );
}
ということで、リサイズと回転のサンプルコードがあり、つまり、リサイズ機能も有しているようなので、少し書き換えれば、サイズ調整も可能になりそうに思いました。
insanity にはすでにアップロード済みのファイルを修正する機能もあるんで、そっちをベースにした方がいいかもしれないし、あるいは、そのものずばりのプラグインもあるような予感もするんだけど、まあ、勉強も兼ねて、ちょっと作ってみました。
<?php
/**
* @package Image Filter
* @version 1.0
*/
/*
Plugin Name: Image Filter
Description: Image Filter plugin fixes image size and image orientation based on EXIF data.
Author: Osamu Shigematsu
Version: 1.0
Author URI: http://shigematsu.org
*/
if (!defined('ABSPATH'))
exit; // Exit if accessed directly
if (!class_exists('ImageFilter')) {
class ImageFilter {
public function __construct() {
add_filter('wp_handle_upload_prefilter',
array($this, 'filter_wp_handle_upload_prefilter'), 10, 1);
add_filter('wp_handle_upload',
array($this, 'filter_wp_handle_upload'), 1, 3);
}
public function filter_wp_handle_upload($file) {
$suffix = strtolower(substr($file['file'], strrpos($file['file'], '.', -1) + 1));
if (in_array($suffix, array('jpg', 'jpeg', 'png', 'gif'))) {
$this->fixImage($file['file']);
}
return $file;
}
public function filter_wp_handle_upload_prefilter($file) {
$suffix = strtolower(substr($file['file'], strrpos($file['file'], '.', -1) + 1));
if (in_array($suffix, array('jpg', 'jpeg', 'png', 'gif'))) {
$this->fixImage($file['tmp_name']);
}
return $file;
}
public function fixImage($file) {
$fixed = false;
$editor = wp_get_image_editor($file);
if (!is_wp_error($editor)) {
// reize image (if needed)
$MAX_WIDTH = $MAX_HEIGHT = 1600;
$size = $editor->get_size();
$width = $size['width'];
$height = $size['height'];
if ($width > $MAX_WIDTH ||
$height > $MAX_HEIGHT) {
$editor->resize($MAX_WIDTH, $MAX_HEIGHT, false);
$fixed = true;
}
// fix orientation
// http://dqn.sakusakutto.jp/2009/02/jpegexiforientaion.html
$exif = @exif_read_data($file);
if (isset($exif['Orientation'])) {
switch ($exif['Orientation']) {
case 1:
break;
case 2:
$editor->filp(false, true);
$fixed = true;
break;
case 3:
$editor->rotate(180);
$fixed = true;
break;
case 4:
$editor->filp(true, false);
$fixed = true;
break;
case 5:
$editor->rotate(270);
$editor->filp(false, true);
$fixed = true;
break;
case 6:
$editor->rotate(270);
$fixed = true;
break;
case 7:
$editor->filp(false, true);
$editor->rotate(90);
$fixed = true;
break;
case 8:
case 9:
$editor->rotate(90);
$fixed = true;
break;
default:
$editor->rotate(0);
$fixed = true;
break;
}
}
if ($fixed) $editor->save($file);
}
}
}
new ImageFilter();
}
動くかどうか、しばらく様子を見てみたいと思います。
