WX340K/341K用の.kicoファイルをImager::AnimeFaceで作る。
WX340K/341K用の.kicoファイルをImager::AnimeFaceで作る。
Imager::AnimeFaceはWX340K用の.kicoファイルを作るのに便利そうだなー、と思っていたのですが。前に書いたように自宅のマシンではmakeできんので放置してたけど、だらっと書いてみた。
WX340K/Kico/AnimeFace.pm
package WX340K::Kico::AnimeFace; use strict; use warnings; use Imager; use Imager::AnimeFace; my %KICO = ( width => 76, height => 62, ); $KICO{ratio} = $KICO{width} / $KICO{height}; my $im = Imager->new(); sub new { my $class = shift; my $self = bless { dst_dir => 'dst', expire_width => ($KICO{width} - 20), @_, }, $class; } sub conv { my $self = shift; my $src_file = shift; my $dst_file = shift; ($dst_file) = $src_file =~ m/((?:\w+[.])*\w+)[.]\w+\z/xms unless $dst_file; my $dst_dir = $self->{dst_dir}; $im->read( file => $src_file ) or return; my $res_list = detect_animeface($im) or return; return unless @$res_list; my $count = 1; foreach my $res (@$res_list) { my $face = $res->{face}; my $face_ratio = $face->{width} / $face->{height}; if ($face_ratio < $KICO{ratio}) { my $new_width = $face->{height} * $KICO{ratio}; my $diff = int( ($new_width - $face->{width}) / 2 ); $face->{width} = int($new_width); $face->{x} -= $diff; $face->{x} = 0 if $face->{x} < 0; } else { my $new_height = $face->{height} / $KICO{ratio}; my $diff = int( ($new_height - $face->{height}) / 2 ); $face->{height} = int($new_height); $face->{y} -= $diff; $face->{y} = 0 if $face->{y} < 0; } next if $face->{width} < $self->{expire_width}; if ($face->{width} < $KICO{width}) { $face->{x} -= int(($KICO{width} - $face->{width}) / 2); $face->{x} = 0 if $face->{x} < 0; $face->{width} = $KICO{width}; $face->{y} -= int(($KICO{height} - $face->{height}) / 2); $face->{y} = 0 if $face->{y} < 0; $face->{height} = $KICO{height}; } my $kico = $im->crop( left => $face->{x}, top => $face->{y}, width => $face->{width}, height => $face->{height}, ); my $kico_filename = "$dst_file.$count"; $kico->scale( xpixels => $KICO{width}, ypixels => $KICO{height}, type => 'nonprop', qtype => 'mixing', ) ->write( file => "$dst_dir/$kico_filename.kico", type => 'jpeg', jpegquality => 90, ); $count++; } } 1;
使う時はこんな感じで。
#!/usr/bin/perl use strict; use warnings; my $src_dir = shift || 'src'; my $dst_dir = shift || 'dst'; use WX340K::Kico::AnimeFace; my $kico = WX340K::Kico::AnimeFace->new( src_dir => $src_dir, dst_dir => $dst_dir, ); foreach my $filename (<$src_dir/*>) { warn "$filename\n"; $kico->conv($filename); }
src/ディレクトリにある画像の顔の部分を切り出して dst/ディレクトリに書き出す感じ。
icon用だからImagerで変換する時にコントラストをやや強調したほうがいいかも?とか思いつつ。