jiichan.com

PROGRAMMING

javascript
CSS
PHP
Java

JS-Image-Resizerを使って画像を高画質で縮小

孫の写真などをサーバーにアップするときには、 元サイズが大きすぎるためアップ前に縮小していました。
縮小にはPHPで作ったものを使用していました。
PHPでの縮小は画質もそこそこ良かったのですが、javascriptでできないかネットでいろいろ探したところ、 ここで JS-Image-Resizerというライブラリを見つけました。 処理速度も速く、さらに高画質であるというところが気に入りました。
使い方を忘れないようにメモしておきます。

フォルダの構成

「imgResize」フォルダーは任意の名前をつけた親フォルダです。
「JS-Image-Resizer」フォルダーの中のresize.jsとresizeWorker.jsの2つのファイルが今回使用したライブラリになります。 risizeWorker.jsはよく分かりませんが内部的に使われているようなのでindex.phpのscriptタグでは読み込みしていません。
「js」フォルダー内のimgResize.jsが「JS-Image-Resizer」を利用しているスクリプトです。 縮小後の画像ファイルは「saveImg」フォルダーに入ります。

  • imgResize
    • css
      • index.css
    • js
      • JS-Image-Resizer
        • resize.js
        • resizeWorker.js
      • imgResize.js
      • jquery-1.8.0.min.js
    • saveImg
    • fileSave.php
    • index.php

画像ファイル選択のinputを配置したHTML

複数の画像ファイルを選択できるようにファイルダイアログではmultipleを指定しています。
divタグのimgAreaは縮小後の画像を表示するエリアです。
縮小にはそこそこ時間がかかるので、縮小後の画像がこのエリアに表示されたのを確認してから保存ボタンでsaveImgフォルダに保存するようにしています。

<!DOCTYPE html>
<html lang="ja">
	<head>
		<title>JS-Image-Resizerを使って画像を高画質で縮小</title>
		<meta charset="UTF-8">
		<link rel="style」」sheet" href="./css/index.css">
		<script src="./js/jquery-1.8.0.min.js"></script>
		<script src="./js/JS-Image-Resizer/resize.js"></script>
		<script src="./js/imgResize.js"></script>
	</head>
	<body>
		<section>
			<h1>JS-Image-Resizerを使って画像を高画質で縮小</h1>
			<ul id="uplog">
				<li>
					<label for="imgFile">img:</label>
					<input type="file" name="upfile" id="imgFile"
								accept="image/*" multiple="multiple">
				</li>
				<li>
					<input type="button" value="画像保存" id="saveImg"> 
				</li>
			</ul>
			<div id="imgArea">
			</div>
		</section>
	</body>
</html&g

ライブラリを読み込んでリサイズする本体のjavascript:imgResize.js

new Resizeの引数などわからないところがありましたが、 自分なりの解釈でどうにか作りこむことができました。

$(function(){
	// キャッシュを無効に
	$.ajaxSetup({cache:false});

	// 縮小後のDataURLを格納するオブジェクト
	var objImage = {};
	var imgViewTag = document.getElementById("imgArea");

	// 画像ファイル選択
	$("#imgFile").on("change", function(e){
		// 縮小済みの表示されている画像を削除
		$("#imgArea").empty();
		objImage = {};
		// 指定された画像ファイルを取得
		var files = e.target.files;
		// 画像を縮小しオブジェクトに格納
		for(var i = 0; i < files.length; i++){
			resizeImageFile(files[i], 600, objImage, imgViewTag);
		}
	});

	// 画像保存
	$("#saveImg").on("click", function(){
		//	画像データが格納されたオブジェクトをJSON形式にしてサーバーに送信
		var jsonImage = JSON.stringify(objImage);
		$.post("./fileSave.php", {"jsonImage":jsonImage},function(resStr){
			alert(resStr);
		});
	});
});

// 画像を縮小する関数
function resizeImageFile(file, newSize, saveImageObj, imageTag) {
	var reader = new FileReader();
	// ファイルの読み込みが完了した場合
	reader.onload = function(evt) {
		var img = new Image();
		img.src = evt.target.result;
		// イメージの読み込みが完了した場合
		img.onload = function() {
			var ow = img.width;
			var oh = img.height;
			var length = Number(newSize);	//	長辺の長さ
			var nw;
			var nh;
			// 縮小後のサイズ計算
			if (ow > oh) {
				nw = length;
				nh = Math.round(oh * length / ow);
			} else {
				nh = length;
				nw = Math.round(ow * length / oh);
			}

			// 元画像の非表示canvas
			var canvasSrc = document.createElement("canvas");
			canvasSrc.width = ow;
			canvasSrc.height = oh;
			var contextSrc = canvasSrc.getContext("2d");

			// canvasに元画像を描画
			contextSrc.drawImage(img, 0, 0, ow, oh);
			// canvasからImageDataを取得
			var imageDataSrc = contextSrc.getImageData(0, 0, ow, oh);

			//	縮小後の非表示canvas
			var canvasNew = document.createElement("canvas");
			canvasNew.width = nw;
			canvasNew.height = nh;
			var contextNew = canvasNew.getContext("2d");

			// canvasにImageDataを作成
			var imageDataNew = contextNew.createImageData(nw, nh);

			// 縮小画像表示用要素
			var imgElem = document.createElement('img');

			/* frameBuffer:変換済み画像情報が入る配列。
				コールバックには画面再描画の処理を登録 */
			var resizer = 
				new Resize(ow, oh, nw, nh, true, true, false,
					function(frameBuffer) {
						// 縮小後の非表示canvasに変換済み画像情報をセット
						for (var i = 0; i < imageDataNew.data.length; i++) {
							imageDataNew.data[i] = frameBuffer[i] & 0xFF;
						}
						// ImageDataを縮小後の非表示canvasに書き出す
						contextNew.putImageData(imageDataNew, 0, 0);
						// 後処理(画像保存など)のためにDataURLをオブジェクトに格納する
						saveImageObj[file.name] = canvasNew.toDataURL("image/jpeg");
						// 縮小画像のプロパティ
						imgElem.src = saveImageObj[file.name];
						imgElem.alt = "縮小後の画像";
						// 表示エリアに追加
						imageTag.appendChild(imgElem);
			  });
			// 縮小する
			resizer.resize(imageDataSrc.data);
		};	//---- img.onload;
	};	//------- reader.onload;
	// 画像ファイルをDataURL形式として読み込む
	reader.readAsDataURL(file);
}

ファイルを保存するPHP

画像保存ボタンをクリックしたときに呼び出されるPHPです。
受け取ったJSONデータをfopen関数でファイルに書き込みしています。

<?php
// jsonデータ受け取り
$jsonImage = filter_input(INPUT_POST, "jsonImage");
// jsonをphpの配列に変換
$aryJsonImage = json_decode($jsonImage);

foreach ($aryJsonImage as $key => $value) {
	$imgpath = "./saveImg/".$key;		// ファイル名
	// ヘッダに「data:image/jpeg;base64,」が付いているので、それを外す
	$img = str_replace("data:image/jpeg;base64,","",$value);
	// イメージ書き込み
	$fp = fopen($imgpath, "w");
	fwrite($fp, base64_decode($img));
	fclose($fp);
}
echo "保存されました";

快適に使わせていただいてます。