CakePHP3/ImageMagic:画像のオリエンテーション(向き)を正しくする

EXIFオリエンテーション(回転)が設定されている画像をアップロードすると、Chromeはそのオリエンテーションを尊重して表示します。 これを回避するためにこんなコンポーネントを作りました:

class FixOrientationComponent extends Component
{
    public function autoRotate(\Imagick $image): \Imagick
    {
        switch ($image->getImageOrientation()) {
        case \Imagick::ORIENTATION_TOPLEFT:
            break;
        case \Imagick::ORIENTATION_TOPRIGHT:
            $image->flopImage();
            break;
        case \Imagick::ORIENTATION_BOTTOMRIGHT:
            $image->rotateImage("#000", 180);
            break;
        case \Imagick::ORIENTATION_BOTTOMLEFT:
            $image->flopImage();
            $image->rotateImage("#000", 180);
            break;
        case \Imagick::ORIENTATION_LEFTTOP:
            $image->flopImage();
            $image->rotateImage("#000", -90);
            break;
        case \Imagick::ORIENTATION_RIGHTTOP:
            $image->rotateImage("#000", 90);
            break;
        case \Imagick::ORIENTATION_RIGHTBOTTOM:
            $image->flopImage();
            $image->rotateImage("#000", 90);
            break;
        case \Imagick::ORIENTATION_LEFTBOTTOM:
            $image->rotateImage("#000", -90);
            break;
        default: // Invalid orientation
            break;
        }
        $image->setImageOrientation(\Imagick::ORIENTATION_TOPLEFT);
        return $image;
    }
}

使い方ですが、こんな感じです:

$image = new \Imagick("/tmp/gazou.jpg");

// Fix orientation info so displays correctly in all browsers
$image = $this->loadComponent('FixOrientation')->autoRotate($image);

ほぼこちらの内容通りです!

stackoverflow.com

ImageMagick:画像の周りにパディングをつけてセンタリングする

シェルを叩く場合

convert original.jpg -gravity center -background white -extent 1024x768 padded.jpg

なお、-gravity centerの場所をこのようにするとうまくいきません:

convert original.jpg -background white -extent 1024x768 -gravity center padded.jpg

なぜだろう…

PHPから行う場合

ここでは、最終的な画像サイズを1024x768にしてセンタリングするとします:

<?php

$newWidth = 1024;
$newHeight = 768;

// 変換前の画像を読み込む
$image = new Imagick('/tmp/original.jpg');

// サイズを取得
$width = $image->getImageWidth();
$height = $image->getImageHeight();

// 新しい画像の中にセンタリングする際の位置を計算
$x = (int) ($newWidth / 2) - (int) ($width  / 2);
$y = (int) ($newHeight / 2) - (int) ($height / 2);

// 新しいjpg画像を作成
$canvas = new Imagick();
$canvas->newImage($newWidth, $newHeight, 'white', 'jpg');

// 新しい画像の上に元画像を合成
$canvas->compositeImage($image, imagick::COMPOSITE_OVER, $x, $y);

// 画像を書き出す
$canvas->writeImage("/tmp/new.jpg");

なお、setImageExtentも使えますがsetGravityで画像をセンタリングできなかったので、上記方法を採用しました。

インチダウン

私は初代IS250のversion Sに乗っているのですが、乗り心地の悪さとロードノイズの多さに悩んできました。 今回、タイヤが寿命に近いためインチダウンを行いました。

インチダウン前のタイヤはブリジストンのレグノGR-XT。サイズは前が225/40R18、後ろが255/40R18です。 インチダウン後のタイヤはブリジストンのレグノGR-XI。サイズは前後共に205/55R16です。

ロードノイズ

ぶっちゃけ、違いがあまりわからないです。 かなり期待していたのでがっかりしました。

3年以上履いた18インチのGR-XTと、新品の16インチのGR-XIで差が感じられないなんて… もしかしたら、タイヤではなくて遮音・吸音のほうが必要なのかもしれませんね。 GR-XTは経年劣化しにくいのかな。

荒れている路面では違いがわからないのですが、舗装が綺麗なところではGR-XTより静かみたいです。 同乗者が指摘してくれました。まあ、舗装が綺麗なところについてはGR-XTでも問題なかったのですが…

乗り心地

若干マイルドになりました。しなやかとは言い難いですし乗り心地がいいとも言い難いのですがまあ、許容範囲になりました。

その他、気づいたこと

ハンドルが軽くなりました。これまではかなり重ステで駐車が面倒だったのですがスイスイ切れるようになりました。 これは嬉しいサプライズでした。なお、スタビリティについては18インチのほうがどっしりしていてよかったです。 16インチはちょっとフワフワした感じがあります。

車が転がりやすくなった気がします

オススメか?

個人的にはインチダウン、いいと思います。次のタイヤも安く買えるし。 ただインチダウンによって乗り心地の悪い車がよくなるわけではない点、 ロードノイズの改善もあまり期待できない点は重要かと思います。

CakePHP3:テンプレートで必要なjavascriptをレイアウトで読み込んだjavascriptの後に読み込ませる

jQuery等のライブラリをレイアウトファイルで読み込ませ、その他のJavaScriptファイルはテンプレート側で必要に応じて読み込む方法をどうやったらよいか、 前から悩んでいたのですが、以下、動く方法が1つ見つかりました。

レイアウトファイルの一部

    <?php

        // 一番最初に読み込みたいjsファイル
        $globalJsFiles = [
            'URI/URI.min',                                           
            'js-cookie/js.cookie',                                      
            'jquery/jquery-3.2.0.min'
        ];
        echo $this->append('globalScripts', $this->Html->($globalJsFiles));
        echo $this->fetch('globalScripts');
        echo $this->fetch('nonGlobalScripts');
    ?>
  </body>
</html>

テンプレートファイル

<?php
    echo $this->append('nonGlobalScripts', $this->Html->script('helloworld'));
?>

jQuery:フォームを送信する前に中身を操作する

<form id='create_order'>
  <input name='firstname'>
</form>

というフォームをajaxでPOSTしたい、だけど、firstnameを差し替えたいとします:

function submitOrder() {
  var data = $("#create_order").serializeArray();

  data.forEach(function (item) {
    if(item.name === 'firstname') {
      item.value = 'thebaker';
    }
  });

  return $.ajax({
    url:      '/orders/add',
    type:     'POST',
    dataType: 'json',
    data:     $.param(data)
  })
}

Outlook:SSL/TLS/STARTTLSの謎

Outlook.comとOffice 365ブラウザ版のOutlookには、IMAPの通信経路の暗号化の選択肢として次の3つがあります:

SSLだと993番に接続できますが143番はNGです。 TLSだと143番に接続できますが993番はNGです。

おそらく、ここでいうSSLは「SSL/TLS」、そしてTLSは「STARTTLS」なのでしょう。

なお、SMTPについては選択肢すらありません。465番を利用せよ、ということでしょうか? 587でSTARTTLSをサポートしてくれると嬉しいのに。

なお、他の落とし穴として:

  • Office 365ブラウザ版のOutlookは、SMTPサーバを指定できない

というのもあります。