Digest::MD5の使い方。

大量の画像ファイルを比較するときに,画像を一回一回読み込むよりも全てのファイルをMD5ハッシュ値にして比較した方が速いんでないのと思ってみて使ってみる。(ホントにそうなのか知らないけど)

とりあえずCPANからインストール。

 $ cpan
 $ install Digest::MD5

・・・とやってみたら既に入ってるらしい。
標準なのねMD5て。


で,画像ファイルを読み込んでハッシュ値を出力するスクリプトはこのようにできる。

use Digest::MD5;

open FILE, 'hoge.bmp' or die "hoge.bmp open error!";
binmode FILE; # バイナリモードにしないとダメ

my $md5 = Digest::MD5->new->addfile(*FILE)->hexdigest;

close FILE;

print 'hoge.bmp : ', $md5, "\n";


ファイルの比較には,生成したMD5ハッシュ値をキーとした連想配列を作成して,

if( exists $dbase{$md5} ){
    # 同じ画像ファイルであった場合の処理
}else{
    # 同じ画像ではなかった場合の処理
}

として処理をした。


Perlはホントに楽だなぁ。

Imagerのインストール

Perlで画像を処理するためのモジュールであるImagerをインストールする。
現在のバージョンは0.62のよう。

まずインストールする前に画像用ライブラリをインストールしておく。
PNGを処理したいからlibpngとついでにlibjpegを入れる。
FCならyumでインストールがすぐできる。
rootになって

 $ yum install libpng-devel
 $ yum install libjpeg-devel


そしてImagerのインストール。
cpanだから1つコマンド打つだけだけど・・・

 $ cpan
 $ install Imager

これもrootでやったほうがいいのかもしれない。
普通ユーザでやったらエラーなった。


これで使えるようになったハズ。


で,使い方。
今回は読み込んだ画像の指定した色の座標を探す。

use Imager;

# 画像ファイル読込み
my $img = Imager->new();
$img->read( file => 'hoge.png', type => 'png' ) or
    die $img->errstr();

# 探したい色を作成
my $search_color = Imager::Color->new( red => 0, green => 128, blue => 255, alpha => 0 );

# 探したい色データがどの座標にあるのかを取得
my $x = 100;
my $search_y;
for( my $y = 0; $y < 100; $y++ ){
    my $color = $img->getpixel( x => $x, y => $y );

    # どんな色が取得されたか見たい場合は
    my ( $red, $green, $blue, $alpha ) = $color->rgba();
    print "R : $red, G : $green, B : $blue, A : $alpha\n";

    # 取得した色が探したかった色かどうかを判定
    if( $color->equals( other => $search_color ) ){
        $search_y = $y;
        last;
    }
}

これは画像処理とはいわない気もするな・・・。

Perlのデバッガ

Perlデバッガの使い方のメモ書き。

起動方法

コマンドラインで以下のように入力。

$ perl -d hoge.pl

操作

移動
s ステップイン。
n ステップオーバー。
r ステップアウト。
c 次のブレークポイントまで実行する。
c line 指定した行まで実行する。
ブレークポイント
b 現在の行にブレークポイントをセットする。
b line 指定した行にブレークポイントをセットする。
b subname 指定したサブルーチンの最初の実行可能行にブレークポイントをセットする。
d 次に実行される行のブレークポイントを削除する。
d line 指定した行のブレークポイントを削除する。
D ブレークポイントを削除する。
探索系
/pattern/ 正規表現の後方探索。最後の/はなくてもOK。
?pattern? 正規表現の前方探索。最後の?はなくてもOK。
ソース表示系
l 次のソース表示(連続で入力することで移動する)。
l subname サブルーチンを表示する。
- 前のソース表示(連続で入力することで移動する)。
v 現在いる行の周辺を表示する。
変数表示系
y 自分で定義した全変数を表示する。
y varname 指定した変数を表示する。
p printと同様に扱うことができる。式の評価も可能。
V パッケージ内の全変数を表示する。
w セットすることで変数が変更されたときに教えてくれる。
サブルーチン表示系
S 全サブルーチン名を表示する。
依存関係表示系
M モジュール一覧を表示。モジュールの呼ばれている場所がわかる。
T スタックのトレースをする。メソッドがどこから呼ばれているかわかる。

プロファイリング

メソッドの起動回数や処理時間などがわかるらしい。

$ perl -d:DProf hoge.pl

結果は tmon.out へ出力される。

splitの使い方。

文字列を分割する。

split [pattern[,string[,max] ] ]

italic;">pattern:区切り文字のパターン文字列(省略時は空白文字/\+/を使用)
italic;">string:文字列(省略時は$_を使用)
italic;">max:分割の最大数(省略時は制限なし)

引数stringを引数patternで分割する。
リストコンテキストでは分割結果をリストとして,スカラコンテキストでは分割された文字列の個数を返す。
引数pattern正規表現を用いて指定する。
引数maxが指定され,分割数が引数maxに達する場合,それ以降の文字列は分割せつ1つの文字列になる。

Example

my $str = "1,2,3,4,5";
my @data = split /,/, $str;

my $filepath = "/home/hoge/2007_10_01.csv";
my @path_spl = split( /(\/|\.|_)/, $filepath );  # 複数の分割文字列も可
my ( $user, $year, $month, $day, $ext ) = (split( /(\/|\.|_)/, $filepath))[4,6,8,10,12];

File::Sortモジュールの使い方。

File::Sortはファイルの内容を行単位でソートし,別のファイルへ出力する。

単純な並べ替え

入力ファイルを I =>
出力ファイルを o =>
で指定する。

#!/usr/bin/perl
use File::Sort qw(sort_file);

sort_file({
   I => "in.txt",
   o => "out.txt",
});

# もしくは
sort_file('file1', 'file1.sorted');

数字で並べ替え

n => 1 を指定する

sort_file({
    n => 1,
    I => "in.txt",
    o => "out.txt",
});

複数ファイルを連結する

m => 1 を指定する。
※ソートは行われない

sort_file({
    m => 1,
    I => ["in1.txt", "in2.txt", "in3.txt"],
    o => "out.txt",
});

逆順に並べる

r => 1 を指定する。

複数ファイルを同時にソートする

sort_file({
    I => ["in1.txt", "in2.txt", "in3.txt"],
    o => "out.txt",
});

ソートキーの位置を指定して並べ替える

k => n を指定する。
nはカラムの番号を表す。

sort_file({
    t => ",",    # 区切り文字の指定
    k => 2,      # 2カラム目
    I => "in.txt",
    o => "out.txt",
});