Imager::transform2による画像生成(2)

前回に引き続き、Imager::Enginesを使って画像を生成する。
今回は、中心からの距離を計算してみる。

少し長ったらしいけど。

use v5.14;
use strict;
use warnings;
use Imager;

my $r = 200;
my $max_dist = sqrt( ($r ** 2) * 2 );

my %opts = (
    width   => ($r * 2) + 1,
    height  => ($r * 2) + 1,
    rpnexpr => 'x y cx 0.5 - cy 0.5 - distance ' . $max_dist . ' / !d 0 0 @d hsv'
);

my $img = Imager::transform2( \%opts );

$img or die $Imager::ERRSTR;

say 'rpnexpr: ', $opts{rpnexpr};
say 'cx: ', $opts{constants}->{cx}, ', cy: ',$opts{constants}->{cy};
$img->write( file => $0 . '.png' );

実行するとこんな感じ。

$ perl aaa.pl
rpnexpr: x y cx 0.5 - cy 0.5 - distance 282.842712474619 / !d 0 0 @d hsv
cx: 200.5, cy: 200.5

20140724-1

確実に中心の色を、R:0,G:0,B:0にしたかったので、
画像の幅と高さを奇数にしている。

中心からの距離を出す方法は、

Nx1 Ny1 Nx2 Ny2 distance -- N

の通り。

中心から一番離れいているのは四隅なので、
あらかじめ四隅と中心の距離を計算しておいて、
求めた距離が0.0から1.0になるように割り算したものをdに代入して、
色の明るさとして使っている。

明るさを計算して1.0を超えたら1.0でクリップすることもできる。

use v5.14;
use strict;
use warnings;
use Imager;

my %opts = (
    width   => 480,
    height  => 320,
    rpnexpr => 'x y cx 0.5 - cy 0.5 - distance 240 / !d 1.0 @d lt 1.0 @d if !dd 0 0 @dd hsv'
);

my $img = Imager::transform2( \%opts );

$img or die $Imager::ERRSTR;
$img->write( file => $0 . '.png' );

こっちを先にやれば良かったかな?

20140724-2

ifの使い方は、

Ncond N-true-result N-false-result if — N

なので難しくはないんだけど、
条件文で使える比較演算子にどれを使えるのかが定かじゃなくて、
ltgtが使えるまでは把握している。

探してみたら、コード読めって話だったので、
ここで”relop”を検索して頂ければと思う。

https://metacpan.org/source/TONYC/Imager-0.99/lib/Imager/Expr.pm#L298

あと、反転する場合は、ifの中を少し変えれば出来る。

use v5.14;
use strict;
use warnings;
use Imager;

my %opts = (
    width   => 480,
    height  => 320,
    rpnexpr => 'x y cx 0.5 - cy 0.5 - distance 240 / !d 1.0 @d lt 0.0 1.0 @d - if !dd 0 0 @dd hsv'
);

my $img = Imager::transform2( \%opts );

$img or die $Imager::ERRSTR;
$img->write( file => $0 . '.png' );

20140724-3

トイカメラ風のエフェクトでよく目にする周辺光量落ちは、
これを応用すればいんじゃないですかね。

おしまい。

Leave a Comment