js 上传图片、压缩、旋转

亲测

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>js上传图片</title>
    <script src="/exif.js"></script>
</head>
<body>
    <input id="file" type="file">

    <script type="text/javascript">
        var fileTypes = ['image/jpeg', 'image/gif', 'image/png'];
        window.onload = function myfunction() {
            var input = document.getElementById('file');
            input.onchange = function () {
                var files = this.files;
                for (var i = 0, len = files.length; i < len; i++) {
                    var file = files[i];
                    if (!fileTypes.includes(file.type)) {
                        alert("只可上传图片")
                        return false;
                    }
                    if (file.size / 1024 > 1025) {
                        photoCompress(file, { quality: 0.3 }, upload_html5);
                    }
                    else {
                        upload_html5(file);
                    }
                }
            };
        }

        function upload_html5(file) {
            var xhr = new XMLHttpRequest();
            xhr.upload.addEventListener("progress", function (e) { }, false);
            xhr.addEventListener("load", function (e) {
                var obj = JSON.parse(e.target.responseText);
                if (obj.code == 200) {
                    alert("上传成功");
                }
                else {
                    alert(obj.message);
                }
            }, false);
            xhr.addEventListener("error", function (e) {
                console.log(e);
                alert("上传失败");
            }, false);
            xhr.addEventListener("abort", function (e) {
                alert("上传取消");
            }, false);

            var fd = new FormData;
            fd.append("file", file);
            fd.append("hallName", '分会场1');
            fd.append("dateTime", '2019-06-21');
            xhr.open("post", "/Common/UploadFile");
            xhr.send(fd);
        }

        /*
        三个参数
        file:一个是文件(类型是图片格式),
        w:一个是文件压缩的后宽度,宽度越小,字节越小
        objDiv:一个是容器或者回调函数
        photoCompress()
         */
        function photoCompress(file, obj, objDiv) {
            var Orientation = null;//ios选择上传图片是图片角度问题
            EXIF.getData(file, function () {
                EXIF.getAllTags(this);
                Orientation = EXIF.getTag(this, 'Orientation');
            });
            var ready = new FileReader();
            /*开始读取指定的Blob对象或File对象中的内容. 当读取操作完成时,readyState属性的值会成为DONE,
             * 如果设置了onloadend事件处理程序,则调用之.同时,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容.*/
            ready.readAsDataURL(file);
            ready.onload = function () {
                canvasDataURL(this.result, obj, Orientation, objDiv)
            }
        }
        function canvasDataURL(path, obj, Orientation, callback) {
            var img = new Image();
            img.src = path;
            img.onload = function () {
                var that = this;
                // 默认按比例压缩
                var w = that.width,
                    h = that.height,
                    scale = w / h;
                w = obj.width || w;
                h = obj.height || (w / scale);
                var quality = 0.7;  // 默认图片质量为0.7
                //生成canvas
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                // 创建属性节点
                var anw = document.createAttribute("width");
                anw.nodeValue = w;
                var anh = document.createAttribute("height");
                anh.nodeValue = h;
                canvas.setAttributeNode(anw);
                canvas.setAttributeNode(anh);

                if (Orientation != "" && Orientation != 1 && Orientation != undefined) {
                    switch (Orientation) {
                        case 6://需要顺时针90度旋转
                            canvas.width = h;
                            canvas.height = w;
                            ctx.rotate(90 * Math.PI / 180);
                            ctx.drawImage(this, 0, -h);
                            break;
                        case 8://需要逆时针90度旋转
                            canvas.width = h;
                            canvas.height = w;
                            ctx.rotate(-90 * Math.PI / 180);
                            ctx.drawImage(this, -w, 0);
                            break;
                        case 3://需要180度旋转
                            ctx.rotate(180 * Math.PI / 180);
                            ctx.drawImage(this, -w, -h);
                            break;
                    }
                }
                else {
                    ctx.drawImage(that, 0, 0, w, h);
                }
                // 图像质量
                if (obj.quality && obj.quality <= 1 && obj.quality > 0) {
                    quality = obj.quality;
                }
                // quality值越小,所绘制出的图像越模糊
                var base64 = canvas.toDataURL('image/jpeg', quality);
                // 回调函数返回base64的值
                callback(base64);
            }
        }
        /**
         * 将以base64的图片url数据转换为Blob
         * @param urlData
         *            用url方式表示的base64图片数据
         */
        function convertBase64UrlToBlob(urlData) {
            var arr = urlData.split(','), mime = arr[0].match(/:(.*?);/)[1],
                bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new Blob([u8arr], { type: mime });
        }

    </script>
</body>
</html>

 exif.js

原文地址:https://www.cnblogs.com/kikyoqiang/p/11074975.html