ネットワークカメラが定期的に撮影したjpeg画像をメールに添付して送ってきてくれるので、
これから添付ファイルを取り出してホームページに掲載するスクリプトを使っていたのだけれど
それだけではつまらないので、複数枚をまとめてGIFアニメにするスクリプトに改造してみた。
仕様:
- メールがサーバーに届くと .mailfilter にしたがってスクリプトが起動する。
- 添付されるファイルは日付と時刻がファイル名になっている。それをいったんどこかのディレクトリにGIFで保存する。このとき画像のリサイズもしておく。
- ディレクトリを読み込み、時系列に並べ替えて、古いものを消去する。
- ディレクトリのGIFをネットで拾ってきたGIFEncoder.class.phpでまとめてしまう。
mail manipulation type 2
#!/usr/local/php/default/bin/php
<?php
require_once '/home/_user_/pear/PEAR/php/Mail/mimeDecode.php';
include '/home/_user_/www/webcam/GIFEncoder.class.php';
// メールデータ取得
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
$params['input'] = file_get_contents("php://stdin");
$params['crlf'] = "\r\n";
$structure = Mail_mimeDecode::decode($params);
//送信者のメールアドレスを抽出
$mail_from = $structure->headers['from'];
$mail_from = addslashes($mail_from);
$mail_from = str_replace('"','',$mail_from);
//署名付きの場合の処理を追加
preg_match("/<.*>/",$mail_from,$str);
if($str[0]!="") {
$str=substr($str[0],1,strlen($str[0])-2);
$mail_from = $str;
}
// 件名を取得
$mail_subject = $structure->headers['subject'];
// ログを作る
$mail_date = $structure->headers['date'];
$tmp = "$mail_date : $mail_subject : $mail_from\r\n";
err_log($tmp);
switch(strtolower($structure->ctype_primary)){
case "text": // シングルパート(テキストのみ)
$mail_body = $structure->body;
break;
case "multipart": // マルチパート(画像付き)
foreach($structure->parts as $part){
switch(strtolower($part->ctype_primary)){
case "text": // テキスト
$mail_body = $part->body;
break;
case "image": // 画像
// 画像の種類を取得する(小文字に変換
$type = strtolower($part->ctype_secondary);
// JPEGチェック(GIFやPNG形式の画像チェックなども可
if($type != "jpeg" and $type != "jpg") { // and $type != "jpg" って必要なの?
continue;
}
// 添付内容をファイルに保存
$fp = fopen("/home/_user_/www/webcam/picture.jpg" ,"w" );
$length = strlen( $part->body );
fwrite( $fp, $part->body, $length );
fclose( $fp );
// 2010.10.12
$path = "/home/_user_/www/webcam";
$fname = $part->d_parameters['filename']; // '20101012.152814.jpg'
$img = imagecreatefromjpeg("$path/picture.jpg"); // JPEGファイルを展開
imagegif($img, "$path/frames/$fname.gif"); // GIF形式で保存
$img_s = imagecreatetruecolor(220, 165); // 小さいサイズ
imagecopyresized($img_s, $img, 0, 0, 0, 0, 220, 165, 320, 240);
imagejpeg($img_s,"$path/picture_s.jpg");
imagegif($img_s, "$path/frm_s/$fname.gif");
imagedestroy($img_s);
$img_xs = imagecreatetruecolor(160, 120); // もっと小さいサイズ
imagecopyresized($img_xs, $img, 0, 0, 0, 0, 160, 120, 320, 240);
imagejpeg($img_xs,"$path/picture_xs.jpg");
imagegif($img_xs, "$path/frm_xs/$fname.gif");
imagedestroy($img_xs);
imagedestroy($img); // メモリを解放
animation("$path/frames","$path/motion.gif",15);
animation("$path/frm_s","$path/motion_s.gif",15);
animation("$path/frm_xs","$path/motion_xs.gif",12); // ファイルサイズを減らすため5分
break;
}
}
break;
default:
$mail_body = "";
}
function animation($indir, $outfile, $cnt)
{
if ( $dh = opendir ($indir) ) {
while ( false !== ( $dat = readdir( $dh ))) {
if ( $dat != "." && $dat != ".." ) {
// ファイル名を配列に保存
$frames[] = $indir.'/'.$dat;
$framed[] = 50;
}
sort($frames);
while (count($frames) > $cnt) {
// 最新 n件より古いファイルを削除
$rmfile=array_shift($frames);
array_shift($framed);
unlink($rmfile);
// err_log("unlink($rmfile);\n");
}
}
closedir ( $dh );
}
$gif = new GIFEncoder($frames, $framed, 0, 2, 0,0,0, "url");
FWrite ( FOpen ( $outfile, "wb" ), $gif->GetAnimation());
// err_log("out:$outfile\n");
}
function err_log($tmp)
{
$len = strlen($tmp);
$fp = fopen("/home/_user_/www/webcam/mailman.log","a" );
fwrite($fp, $tmp, $len);
fclose($fp);
}
?>
参考:
メール受信時に PHP スクリプトを起動して自動処理させる方法
stdinからのメール処理でメール情報を取得する
Class: GIF images into animated GIF with native PHP class

