Imagerで画像をモノクロにする
最近、ちょっとコードが長過ぎる気がしたので、
今日は短めのコードを載せようと思う。
まずは長ったらしい方から。
use v5.14;
use strict;
use warnings;
use Imager;
if ( (not @ARGV) or (not -e $ARGV[0]) ) {
say "Usage:
perl $0 file_path";
exit( 0 );
}
my $img_src = Imager->new( file => $ARGV[0] )
or die Imager->errstr();
# Y = (0.299 * red) + (0.587 * green) + (0.114 * blue)
my $img_dst = Imager::transform2( {
channels => 1,
constants => {
fr => 0.299,
fg => 0.587,
fb => 1.0 - 0.299 - 0.587
},
rpnexpr => 'x y getp1 !pix @pix red fr * @pix green fg * + @pix blue fb * + int !yy @yy @yy @yy rgb'
}, $img_src );
$img_dst or die $Imager::ERRSTR;
$img_dst->write( file => $0 . '.jpg', jpegquality => 90 );
ありがちな係数で輝度を算出して、それをR,G,Bに格納してる。
でも、こんな異常な努力は必要なくて、
R,G,Bに任意の係数を掛けるだけなら、こう書ける。
use v5.14;
use strict;
use warnings;
use Imager;
if ( (not @ARGV) or (not -e $ARGV[0]) ) {
say "Usage:
perl $0 file_path";
exit( 0 );
}
my $img_src = Imager->new( file => $ARGV[0] )
or die Imager->errstr();
my $img_dst = $img_src->convert(
matrix => [ [ 0.299, 0.587, (1.0 - 0.299 - 0.587) ] ]
);
$img_dst->write( file => $0 . '.jpg', jpegquality => 90 );
ところで、ありがちな係数で輝度を求めてもいんだけど、
個人的には画像にあった係数を掛けるべきだと思う。
たとえば、今回の例だとピンク色だし、
せっかく露出補正で明るい方に振ったので、
モノクロに変換した後も明るめになって欲しい。
という訳で、適当に係数を変えて変換してみる。
use v5.14;
use strict;
use warnings;
use Imager;
if ( (not @ARGV) or (not -e $ARGV[0]) ) {
say "Usage:
perl $0 file_path";
exit( 0 );
}
my $img_src = Imager->new( file => $ARGV[0] )
or die Imager->errstr();
my $img_dst = $img_src->convert(
matrix => [ [ .4, .4, .2 ] ]
);
$img_dst->write( file => $0 . '.jpg', jpegquality => 90 );
ほんとに適当なんだけど、
こんな感じにすると、花のところが少し明るくなる。
という訳で、元画像。
ありがちな係数と、適当な係数で変換した画像。
convertの詳しい使い方は、Imager::Transformationsをどうぞ。
おしまい。



Leave a Comment