あんまりよくねーな。このプラグイン。
画像向きもうまく変更されなかったり。。。
と思ったが、laravelでも同様のバグがおきた。
ということで強調して解決方法書いておく。
imagickで画像を読み込み。
向きを直して上書き。
// ここで画像の向きを変更する
$imagick = new \Imagick();
$imagick->readImage($_FILES['img']['tmp_name']);
$imagick->autoOrient();
$imagick->writeImage($_FILES['img']['tmp_name']);
例えば laravel なら
if($request->all()) {
$imagick = new \Imagick();
$imagick->readImage($_FILES['image']['tmp_name']);
$imagick->autoOrient();
$imagick->writeImage($_FILES['image']['tmp_name']);
こんな感じね。
2019/01/22
imagick を使って、
画像向きを変更。
cakephp3で画像をアップロードしたい。
昔はmediapluginがあったが、時代が変わったようなので新しい方法を。
Josegonzalez/Upload.Upload を使おう。
Josegonzalez/Upload.Upload は composer でインストール済みとする。
・uploadsテーブルの作成
id , social_id , img , dir , created
・uploadsTableモデル
<?php
namespace App\Model\Table;
use Cake\Validation\Validator;
use Cake\ORM\RulesChecker;
use Cake\ORM\Query;
use Search\Manager;//Searchするときに必須
use Cake\ORM\TableRegistry;
use Cake\I18n\Time;
use Cake\Datasource\ConnectionManager;
use Google\Cloud\Storage\StorageClient;
class UploadsTable extends AppTable
{
var $thumb = [
'thumbnail' => [
'600x381'
],
'crop' => [
'73x73'
]
];
public function initialize(array $config)
{
$this->addBehavior('Josegonzalez/Upload.Upload', [
'img' => [
'nameCallback' => function ($data, $settings) {
$ext = mb_strtolower(pathinfo($data['name'], PATHINFO_EXTENSION));
return md5(uniqid(rand(),1)).".".$ext;
},
'transformer' => function ($table, $entity, $data, $field, $settings) {
// ここで画像の向きを変更する
$imagick = new \Imagick();
$imagick->readImage($_FILES['img']['tmp_name']);
$imagick->autoOrient();
$imagick->writeImage($_FILES['img']['tmp_name']);
$res = [
$data['tmp_name'] => $data['name']
];
foreach ($this->thumb as $key => $v) {
foreach ($v as $s) {
$extension = mb_strtolower(pathinfo($data['name'], PATHINFO_EXTENSION));
// サムネイルを保存
$tmp = tempnam(sys_get_temp_dir(), 'upload') . '.' . $extension;
$img_size = explode("x",$s);
$size = new \Imagine\Image\Box($img_size[0],$img_size[1]);
if($key == 'thumbnail'){
$mode = \Imagine\Image\ImageInterface::THUMBNAIL_INSET;
} elseif($key == 'crop') {
$mode = \Imagine\Image\ImageInterface::THUMBNAIL_OUTBOUND;
}
$imagine = new \Imagine\Gd\Imagine();
// Save that modified file to our temp file
$imagine->open($data['tmp_name'])
->thumbnail($size, $mode)
->save($tmp);
$res[$tmp] = $key.'_'.$s.'_' . $data['name'];
}
}
return $res;
},
],
]);
}
public function validationDefault(Validator $validator)
{
// バリデータにプロバイダーを追加
$validator->setProvider('upload', 'Josegonzalez\Upload\Validation\DefaultValidation');
$validator ->add('img', [
'uploadedFile' => [
'rule' => ['uploadedFile', ['types' => ['image/jpeg','image/png','image/gif']]],
'last' => true,
'message' => 'gif , jpeg , png のみアップロード可能です。'
]
])
->add('img', 'fileUnderPhpSizeLimit', [
'rule' => 'isUnderPhpSizeLimit',
'message' => 'ファイルサイズが大きすぎます。',
'provider' => 'upload'
])
->add('img', 'fileUnderFormSizeLimit', [
'rule' => 'isUnderFormSizeLimit',
'message' => 'ファイルサイズが大きすぎます。',
'provider' => 'upload'
]);
return $validator;
}
}
画像のアップロードフォームは以下を参考にしてね
https://qiita.com/ma7ma7pipipi/items/1a1081b0dd71365a3e7e
メモ
画像をジャストフィットリサイズ、クロップしたい場合は以下を指定
$mode = \Imagine\Image\ImageInterface::THUMBNAIL_OUTBOUND;
上記出いけると思うが、これを手作業にすれば
function resizeToFit( $targetWidth, $targetHeight, $sourceFilename )
{
// Box is Imagine Box instance
// Point is Imagine Point instance
$imagine = new \Imagine\Gd\Imagine();
$target = new \Imagine\Image\Box($targetWidth, $targetHeight );
$originalImage = $imagine->open( $sourceFilename );
$orgSize = $originalImage->getSize();
if ($orgSize->getWidth() > $orgSize->getHeight()) {
// Landscaped.. We need to crop image by horizontally
$w = $orgSize->getWidth() * ( $target->getHeight() / $orgSize->getHeight() );
$h = $target->getHeight();
$cropBy = new \Imagine\Image\Point( ( max ( $w - $target->getWidth(), 0 ) ) / 2, 0);
} else {
// Portrait..
$w = $target->getWidth(); // Use target box's width and crop vertically
$h = $orgSize->getHeight() * ( $target->getWidth() / $orgSize->getWidth() );
$cropBy = new \Imagine\Image\Point( 0, ( max( $h - $target->getHeight() , 0 ) ) / 2);
}
$tempBox = new \Imagine\Image\Box($w, $h);
$img = $originalImage->thumbnail($tempBox, \Imagine\Image\ImageInterface::THUMBNAIL_OUTBOUND);
// Here is the magic..
// $res = $img->crop($cropBy, $target);
$img->crop($cropBy, $target)
->save(WWW_ROOT."/files/hoge3.png");
// pd($cropBy);
// die;
//
// $tempBox = Box($w, $h);
// $img = $originalImage->thumbnail($tempBox, ImageInterface::THUMBNAIL_OUTBOUND);
// // Here is the magic..
// return $img->crop($cropBy, $target); // Return "ready to save" final image instance
}
上記のようなメソッドになりますね。
ただ、処理結果はほぼ同じ。