メールで送られて来たjpg画像をまとめてgifアニメにする

ネットワークカメラが定期的に撮影したjpeg画像をメールに添付して送ってきてくれるので、
これから添付ファイルを取り出してホームページに掲載するスクリプトを使っていたのだけれど
それだけではつまらないので、複数枚をまとめてGIFアニメにするスクリプトに改造してみた。

仕様:

  1. メールがサーバーに届くと .mailfilter にしたがってスクリプトが起動する。
  2. 添付されるファイルは日付と時刻がファイル名になっている。それをいったんどこかのディレクトリにGIFで保存する。このとき画像のリサイズもしておく。
  3. ディレクトリを読み込み、時系列に並べ替えて、古いものを消去する。
  4. ディレクトリの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

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>