September 2007
Entries Title
Preview 用に画像を crop & scale する
- Date
- 2007-09-05 (Wed)
- Category
- Processing
画像を受け取って、それからPreview 用の Thumbnail を生成する、というのは Web app でよくあるシチュエーションだと思います。自分用の備忘録として、今日思いついた方法をメモしておきます。
変換元 / 変換先がどんな画像であれ、crop & scale に必要な情報は
- 元画像 (source)
- X 座標
- Y 座標
- 幅
- 高さ
- 先画像 (destination)
- X 座標
- Y 座標
- 幅
- 高さ
この8つです。今回はこの8つのうち、4つの情報、変換元 / 変換先それぞれの幅と高さがわかっている状態から、出来るだけ、aspect 比を変えないようにするアルゴリズムを考えてみました。PHP で手続き風に書きますが、言語(当然ですが)は問いません。
function calcResizedBounds ($w0, $h0, $w1, $h1)
{
switch (true)
{
case ($w0 > $h0):
$r = processLandscape($w0, $h0, $w1, $h1);
break;
case ($w0 < $h0):
$r = processPortrait($w0, $h0, $w1, $h1);
break;
case ($w0 == $h0):
$r = processSquare($w0, $w1, $h1);
break;
}
return $r;
}
function processLandscape ($w0, $h0, $w1, $h1)
{
$src_y = 0;
$src_h = $h0;
$ratio = $h0 / $h1;
$src_w = floor($w1 * $ratio);
$src_x = floor(($w0 - $src_w) / 2);
return array($src_x, $src_y, $src_w, $src_h);
}
function processPortrait ($w0, $h0, $w1, $h1)
{
$src_x = 0;
$src_w = $w0;
$ratio = $w0 / $w1;
$src_h = floor($h1 * $ratio);
$src_y = floor(($h0 - $src_w) / 2);
return array($src_x, $src_y, $src_w, $src_h);
}
function processSquare ($side, $w1, $h1)
{
switch (true)
{
case ($w1 > $h1):
$src_x = 0;
$src_w = $side;
$ratio = $side / $w1;
$src_h = floor($h1 * $ratio);
$src_y = floor(($side - $src_w) / 2);
break;
case ($w1 < $h1):
$src_y = 0;
$src_h = $side;
$ratio = $side / $h1;
$src_w = floor($w1 * $ratio);
$src_x = floor(($side - $src_w) / 2);
break;
case ($w1 == $h1):
$src_x = 0;
$src_y = 0;
$src_w = $side;
$src_h = $side;
break;
}
return array($src_x, $src_y, $src_w, $src_h);
}
こんな風に使います。
$dst_x = 0; $dst_y = 0; $dst_w = $w1; $dst_h = $h1; $src_x = null; $src_y = null; $src_w = null; $src_h = null; list($src_x, $src_y, $src_w, $src_h) = calcResizedBounds($w0, $h0, $w1, $h1);
Symfony で Json を出力
- Date
- 2007-09-05 (Wed)
- Category
- symfony
Symfony にも、Prototype と連携する plugin や、Askeet のサンプルでも出てくる Symfony 同梱の helper などがあります。でも最終的には結局しっくりこないで、自分でみっちりチューニングした javascript を書いてしまうことが僕は多いです。。そんな時に、僕だけかもしれないけれど、Symfony で JSON 形式の書き出しをする事があります。Symfony 側、例えば app.yml に設定を集中して書いて interface を司る javascript でも同じ設定を使い回すため、とか。
で、今日すこしハマったので、tip として挙げておきます。どういう理由なのか、自分ではさっぱりわからなかったのだけれど…
例えば、以下のような Symfony の View があります。(抜粋)
var Setting = {};
<?php foreach ($arr as $key => $val): ?>
Setting.<?php echo $key; ?> = '<?php echo $val; ?>';
<?php endforeach; ?>
これを <script src="〜〜"></script> として読み込ませてみるんだけど、javascript runtime が解釈してくれない。。ソースを browser で見て、普通にテキストとしてコピペすると、使えるのに…全体が読み込まれないならまだわかるんだけど、一部だけってのも不可解すぎた。
諦めかけた時に、ふと、ページの content-type を text/javascript から、application/x-javascript に変えてみたら、全てのオブジェクトが認識されるようになりました。/apps/modules/MODULE/config/view.yml に以下のように書きました。
default: has_layout: off http_metas: content-type: application/x-javascript
white space の扱い、とかそういうのだと思うけれど。こういう事もありますよ、という事で。