Imagerでポスタリゼーション
だいぶ暑くって、うまく頭が回らないですが、
ポスタリゼーションに挑戦してみようと思います。
難しいところは、0から255の直線的な配列を階段状にするところ。
要素数が256個を10区間に分割すると、25.6個ずつ・・・暑い。。。
という訳で、分かりやすく8区間でやってみましょう。
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 = Imager->new( file => $ARGV[0] )
    or die Imager->errstr();
my $n = 8;
my @table = 0..255;
my $st = 0;
foreach my $i (1..$n) {
    my $en = int( ($i * scalar(@table)) / $n );
    my $val = int( 255 * (($i - 1) / ($n - 1)) );
    for (my $j=$st; $j<$en; $j++) {
        $table[$j] = $val;
    }
    printf( "%3d <= x < %3d : %3d\n", $st, $en, $val );
    $st = $en;
}
$img->map( all => \@table );
$img->write( file => $0 . '.jpg', jpegquality => 90 );
すると、こんな感じで階段状になります。
$ perl aaa.pl 20140803-1.jpg
  0 <= x <  32 :   0
 32 <= x <  64 :  36
 64 <= x <  96 :  72
 96 <= x < 128 : 109
128 <= x < 160 : 145
160 <= x < 192 : 182
192 <= x < 224 : 218
224 <= x < 256 : 255
あと、21行目を、
    my $val = int( 255 * (($i - 1) / ($n - 1)) );
から、
    my $val = int( 255 * ((($i - 1) / ($n - 1)) ** .5) );
に変えると、ふわっと明るくなります。
という訳で、元画像とポスタリゼーションはこちら。
あと、ふわっと明るくなった画像。
ちなみに、Imager::Filtersを見ると、ポスタリゼーションが存在するので、
こんな感じで簡単に書けます。
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 = Imager->new( file => $ARGV[0] )
    or die Imager->errstr();
my $n = 8;
$img->filter( type => 'postlevels', levels => $n )
  or die $img->errstr;
$img->write( file => $0 . '.jpg', jpegquality => 90 );
ちょっと、仕上がりが違うっぽいけどね。
おしまい。



Leave a Comment