jQuery.uploadでアップロード画像のサムネイルの作成

Ajaxを使ったメールフォームとかってやっぱり素敵ですよね。
以前仕事で写真投稿付きのフォームを作らざるを得なかったので、どうせならということでAjax化しました。
というわけでjQuery.uploadを使って写真をアップロードして、サムネイルを表示するチュートリアルです。

2011-12-03追記:デモ作りました。jQuery.uploadを使ったフォームのデモを作りました。

コード

html
[html]
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>upload form</title>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.upload-1.0.2.min.js"></script>
<script type="text/javascript" src="script.js"></script>
</head>
<body>

<form method="post" enctype="multipart/form-data" action="upload.php">
<input type="file" value="" id="img" name="img">
<input type="submit" id="submit" value="送信">
<div id="preview">ここにプレビューが表示されます</div>
</form>

</body>
</html>
[/html]

script.js
[js]
jQuery(function($){

$(‘#img’).change(function() {
var preview = $(‘#preview’);
//現在表示されているものを消す。
preview.find("img").fadeOut(300);

//アップロード、表示
$(this).upload(‘upload.php’,$("form").serialize(),function(html){
preview.html(html).animate({"height":preview.find("img").height()+"px"},300,function(){
preview.find("img").hide().fadeIn(300);
});
},’html’);
});

});
[/js]

upload.php
[php]
<?php

//前にアップロードされた写真のファイル名
$postPhotoName = $_POST["postPhotoName"];

//古いファイルの削除
if($postPhotoName){

unlink("./img/".$postPhotoName);
unlink("./img/thumb-".$postPhotoName);
}

//アップロードされたファイルの情報を取得
$fileName = basename(date("U")."-".$_FILES[‘img’][‘name’]);
$fileType = $_FILES[‘img’][‘type’];
$fileTmpName = $_FILES[‘img’][‘tmp_name’];

$result = false;
if(preg_match("/jpeg/",$fileType)){
if (move_uploaded_file($fileTmpName, ‘./img/’ . $fileName)) {
include(‘class.image.php’);
//サムネイル作成
list($width, $height, $type, $attr) = getimagesize(‘img/’.$fileName);
$thumb = new Image(‘img/’.$fileName);
$thumb->name(‘thumb-‘.basename($fileName,".jpg"));
if($width>$height){
if($width > 200) $thumb->width(200);
}else{
if($height > 200) $thumb->height(200);
}
$thumb->save();
$result = true;
} else {
echo ‘保存にしっぱいしたぜよ。’;
}

}else{
unlink($fileTmpName);
echo "jpegじゃないぜよ。";
}

if($result == true){
?>
<img src="<?php echo ‘./img/thumb-‘.$fileName;?>">
<input type="hidden" value="<?php echo $fileName?>" name="postPhotoName" id="postPhotoName">
<?php
}
[/php]

概要

HTMLには特に特別なことはしていません。ただ、js無効のユーザーの為に、
[html]
<form enctype="multipart/form-data">
[/html]
とします。

jsですが、7行目でアップロードの方をやっています。
[js]
$("hoge").upload([データを受け取るCGIとかPHPのパス],[データ],[コールバック]);
[/js]
として使います。
また、コールバック関数の引数で、通信をしたサーバー側のスクリプトのHTMLを取得が出来ます。
なので、今回の場合、upload.phpで送信されたファイルをサムネイルに加工したものを表示出来れば良いわけです。

phpは、受け取った画像データをGDでサムネイルに加工しているだけです。class.image.phpを使っています。また、写真用なので、jpeg以外弾くようにしています。

PHPSPOT開発日誌にPHPでの画像のリサイズ、切り抜きが自由自在「class.image.php」という記事が載っているのでそちらを参照ください。

また、このままだと、サーバーにファイルが溜まりっぱなしになるので、
[php]
<input type="hidden" value="<?php echo $fileName?>" name="postPhotoName" id="postPhotoName">
[/php]
を結果を返すときに一緒に返します。そして、また違うものがアップロードされたときには、ここの値を使って、サーバー上のファイルを削除します。それでもアップロードした後に”戻る”とかをされてしまうとサーバーに残ってしまうので、定期的にcronで削除するようにしてたりします。

これをさらにPHPMailer等に投げて、写真投稿つきのメールフォームにしています。

他にもいくつかjQueryでファイルのアップロードができるjsはjQuery File Upload等いくつかあるので、また触ってみたいですね。