纯前端压缩上传图片 (兼容移动端苹果)

 class Compress {

            constructor(file, option) {
                this.file = file;
                this.config = Object.assign({
                    quality: 0.9
                }, option);

                return this.process();
            }

            //支持压缩的格式
            get mimeTypes() {
                return {
                    PNG: "image/png",
                    JPEG: "image/jpeg",
                    WEBP: "image/webp",
                    BMP: "image/bmp"
                }
            };

            get supportTypes() {
                    return Object.keys(this.mimeTypes).map(type => this.mimeTypes[type]);
                }
                //判断格式是否支持
            isSupportedType(type) {
                return this.supportTypes.includes(type);
            }

            process() {
                this.outputType = this.file.type;
                if (this.isSupportedType(this.file.type) == false) {
                    return Promise.reject(new Error("不支持该文件类型"));
                }

                return this.getOriginImage().then(img => {
                    return this.getCanvas(img);
                }).then(canvas => {
                    let scale = 1;

                    if (this.config.maxWidth) {
                        scale = Math.min(1, this.config.maxWidth / canvas.width);
                    }
                    if (this.config.maxHeight) {
                        scale = Math.min(1, scale, this.config.maxHeight / canvas.height);
                    }


                    return this.doScale(canvas, scale);
                }).then(result => {
                    return new Promise((resolve, reject) => {
                        resolve(this.toBlob(result));
                    })
                })
            }

            //通过file 初始化 image
            getOriginImage() {
                return new Promise((resolve, reject) => {
                    let img = new Image();
                    img.onload = () => {
                        resolve(img);
                    };
                    img.onerror = () => {
                        reject("图片加载失败");
                    };

                    img.src = URL.createObjectURL(this.file);
                })
            }

            getCanvas(img) {
                return new Promise((resolve, reject) => {
                    // 通过得到图片的信息来调整显示方向以正确显示图片,主要解决 ios 系统上的图片会有旋转的问题
                    EXIF.getData(img, () => {
                        let orientation = EXIF.getTag(img, "Orientation") || 1;

                        let canvas = document.createElement("canvas");


                        let ctx = canvas.getContext("2d");

                        if (orientation == 6) {
                            canvas.width = img.height;
                            canvas.height = img.width;
                            ctx.rotate(90 * Math.PI / 180);
                            ctx.drawImage(img, 0, 0, img.width, img.height, 0, -img.height, canvas.height, canvas.width);

                        } else {
                            canvas.width = img.width;
                            canvas.height = img.height;
                            ctx.drawImage(img, 0, 0);
                        }

                        resolve(canvas);
                    });
                })
            }

            doScale(source, scale) {
                if (scale == 1) {
                    return Promise.resolve(source);
                }

                let mirror = document.createElement("canvas");
                mirror.width = Math.ceil(source.width * scale);
                mirror.height = Math.ceil(source.height * scale);

                let mctx = mirror.getContext("2d");

                mctx.drawImage(source, 0, 0, source.width, source.height, 0, 0, mirror.width, mirror.height);


                return Promise.resolve(mirror);
            }

            // 这里把 base64 字符串转为 blob 对象
            toBlob(result) {
                let dataURL = result.toDataURL(this.outputType, this.config.quality);
                let buffer = atob(dataURL.split(",")[1]).split("").map(char => char.charCodeAt(0));
                let blob = new Blob([new Uint8Array(buffer)], {
                    type: this.outputType
                });
                return {
                    blob: blob,
                    url: dataURL
                };
            }

        }
 // 头像压缩
        document.querySelector('#upload').addEventListener('change', function() {
            var fileSrc = this.files[0];
            new Compress(fileSrc, {
                maxWidth: 1000,
                maxHeight: 1000,
                quality: 0.7
            }).then(function(data) {
                //这里写回调函数,data会传入两个属性,url:压缩后图片url,blob:压缩后图片blob值
                var imgSrc = data.url;
                console.log(this);
                $(".filehead").children('img').prop("src", imgSrc);
                $(".filehead").children('#upload').attr("value", imgSrc);

            }, function(err) {
                //这里写异常处理
                console.log(err);
            })
        });

 

posted @ 2018-12-12 09:38  青幽草  阅读(669)  评论(0编辑  收藏  举报