アップロード画像をjsで圧縮してEXIFを見て回転して表示・POSTする

#概要
フォームで画像をアップロードする際，圧縮・EXIF-Orientationを見て回転したうえで，送信・プレビューしたい場合がある。
input-fileで画像を受け取り，圧縮したdataUrlに変換することを考える。
また画像は，今回はただ圧縮するのではなく，正方形になるようにcropしてる。（この辺は，canvasをいじればいろいろできる）


#依存
jquery https://github.com/jquery/jquery
exif-js https://github.com/exif-js/exif-js

#要点
1.formObjectをBlobURLに変換
2.BlobURLをimageObjectに変換
3.imageObjectを圧縮して回転してcropしてdataUrlにて出力（canvas利用）



#ソース

```html:sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
<script type="text/javascript" src="jquery-1.12.3.min.js"></script>
<script type="text/javascript" src="exif.js"></script>
<script type="text/javascript">
(function($) {

    $.fileImageViewer = function() {

        // base64dataURLから圧縮したbase64dataURLを生成
        function resizeImage(src, size, callback) {
            var img = new Image();
            img.onload = function() {
                EXIF.getData(img, function() {
                    var dst = _resize(img, size)
                    callback(dst);
                    img = null; // for leak
                });
            };
            img.src = src;
            return;
        }

        // imageObjectから圧縮したbase64dataURLを生成
        function _resize(img, compressSize) {
            var exif = img.exifdata.Orientation
            var raw_width = img.width;
            var raw_height = img.height;
            var canvas = document.createElement('canvas');
            canvas.width = compressSize;
            canvas.height = compressSize;
            var ctx = canvas.getContext('2d');
            ctx.translate(canvas.width / 2, canvas.height / 2);
            switch (exif) {
            case 1:
                break;
            case 2: // vertical flip
                ctx.scale(-1, 1);
                break;
            case 3: // 180 rotate left
                ctx.rotate(Math.PI);
                break;
            case 4: // horizontal flip
                ctx.scale(1, -1);
                break;
            case 5: // vertical flip + 90 rotate right
                ctx.rotate(0.5 * Math.PI);
                ctx.scale(1, -1);
                break;
            case 6: // 90 rotate right
                ctx.rotate(0.5 * Math.PI);
                break;
            case 7: // horizontal flip + 90 rotate right
                ctx.rotate(0.5 * Math.PI);
                ctx.scale(-1, 1);
                break;
            case 8: // 90 rotate left
                ctx.rotate(-0.5 * Math.PI);
                break;
            default:
                break;
            }
            var dx = -canvas.width / 2;
            var dy = -canvas.height / 2;
            var dw = canvas.width;
            var dh = canvas.height;
            var sx = Math.max((raw_width - raw_height) / 2, 0);
            var sy = Math.max((raw_height - raw_width) / 2, 0);
            var sw = Math.min(raw_height, raw_width);
            var sh = Math.min(raw_height, raw_width);
            ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);
            var url = canvas.toDataURL('image/jpeg');
            ctx = null;
            canvas = null;
            return url;
        }

        return {
            resizeImage : resizeImage
        }
    };
    
})(jQuery);
</script>
<script type="text/javascript">
	$(function() {
	    var $viewer = $('#picture');
	    var $file   = $('#file');

	    $file.change(function(){
	        var file = $file[0].files[0];
	        if(!file) return;
	        var src = window.URL.createObjectURL(file); // blob file
	        $.fileImageViewer().resizeImage(src, 100, function(dst){
	            $viewer.attr("src", dst);
	        });
	    });
	});
</script>
</head>
<body>
	<img src="" id="picture">
	<input type="file" accept="image/*" id="file">
</body>
</html>
```
#改善点
・formObject->BlobURL->imageObject->dataURLと変換を何度も挟んで非効率ではないか？
・スマホでやるとメモリ不足で落ちる時がある。なにか対処法はないか？

ご指摘あればぜひ宜しくお願いします。