にっきダイアリー

はてなダイアリーからはてなblogに移動してみました。

Imager を使ってモザイクをかける

指定したディレクトリにある画像ファイルの同一箇所にモザイクをかけるスクリプト

スクリプトの内容自体は書くのに30分もかからない簡単なものだ。

ただ Imager のマニュアル読むのにその倍の時間を要した。英語が全く読めないわけじゃないけど、マニュアルをぱっと見た時にどこを自分が注目すべきなのかが判らないんだよね。たとえば、

切り抜きをしたい→切り抜き処理は英語だとなんて言うんだろう\(^o^)/

とかさ。私は典型的な、読めるけど書けない人。てわけで、また crop を忘れた時のために……

use strict;
use warnings;
use Win32::Die;
use Imager;

&Main;

BEGIN{
  $| = 1;
}

sub Main {
	my $imgdir = 'temp/'; # マスキングしたい画像のあるフォルダ
	my @mask = (48,538,102,166); # マスク位置(x,y,w,h)
	my $me = MASK_MAIN->new();
	$me->go($imgdir,@mask);
}

package MASK_MAIN;
#----------------------------------------------------------
# コンストラクタ
#----------------------------------------------------------
sub new {
	my $proto = shift;
	my $class = ref($proto) || $proto;
	my $self = {
	};
	bless $self, $class;
}
#----------------------------------------------------------
# 実行
#----------------------------------------------------------
sub go {
	my $self = shift;
	my $idir = shift || 'temp/';
	my @prm = @_;
	opendir(my $dh, $idir) or die;
	while(my $ent = readdir($dh)){
		my $img = $idir.$ent;
		next if($img =~ /^\./);
		next if(-d $img);
		next unless($img =~ /\.(png||bmp||jpg||gif)$/);
		my $ext = $1;
		print "Masking ".$img."\n";
		$self->mask($img,@prm);
	}
	closedir($dh);
}

#----------------------------------------------------------
# マスキング処理
#----------------------------------------------------------
sub mask {
	my $self = shift;
	my $file = shift;
	my $left = shift || 0;
	my $top = shift || 0;
	my $width = shift || 0;
	my $height = shift || 0;
	return unless($file and $width and $height);
	my $img = Imager->new;
	# 画像読み込み
	if($img->read(file => $file)){
		# マスクしたい部分だけを切り抜いて別のオブジェクトを作成
		my $mkimg = $img->crop(left => $left, top => $top, width => $width, height => $height);
		# モザイク処理
		$mkimg->filter(type=>"mosaic", size=>10);
		# 元画像に処理した画像を貼り付け
		$img->paste(left => $left,top => $top,img => $mkimg);
		# 書き出し
		$img->write(file => $file)  or warn $img->errstr;
	}
	else{
		warn $img->errstr;
	}
}