5实现移动端照片压缩,旋转,上传

530 阅读3分钟

1.H5实现本地文件的照片上传(包含其他文件)

2.input的change事件。图片的加载

3.ios会出现图片的旋转

4.利用canvas实现图片的旋转和压缩

5.具体的代码实现(封装成js插件):

//图片压缩工具
var photoCompression = {
    option : {
        dom : '', //jquery input[type='file']对象
        width : 0, //压缩宽度
        height : 0, //压缩高度
        quality : 0.7, //压缩质量
        orientation : null, //照片方向角
        start : function(){}, //开始读取文件回调
        error : function(){}, //读取文件错误回调
        success : function(dataURL){}, //读取文件成功回调
        end : function(dataURL){}, //压缩结束回调
    },
    init : function(opt){
        var _this = this;
        var _this = this,option = _this.option;
        option = $.extend(option,opt);
        _this.chooseFile();
    },
    chooseFile : function(){
        var _this = this;
        var obj = {width:_this.option.width,height:_this.option.height,quality:_this.option.quality};
        _this.option.dom.unbind("change");
        _this.option.dom.change(function(){ 
            var file = this.files[0];

            //获取照片方向角属性,用户旋转控制  
            EXIF.getData(file,function(){
                EXIF.getAllTags(this);   
                var orientation = EXIF.getTag(this, 'Orientation'); 
                _this.option.orientation = orientation;
            });

            if (window.FileReader) { 
                var reader = new FileReader();    
                reader.readAsDataURL(file);
                reader.onabort = function(){ //中断
                    alert("读取图片已中断,请重新处理");
                };
                reader.onerror = function(){ //出错
                    _this.option.error();
                };
                reader.onloadstart = function(){ //开始
                    _this.option.start();
                };
                reader.onprogress = function(){ //正在读取
                };
                reader.onload = function(e){ //成功读取
                    var file_url = e.target.result;    //e.target.result就是最后的路径地址
                    _this.option.success(file_url);
                    // 调用函数处理图片                 
                    _this.dealImage(file_url, obj ,function(base){
                        _this.option.end(base);
                    });
                };
                //监听文件读取结束后事件    
                reader.onloadend = function (e) { //读取完成,无论成功失败
                };    
           }else{
                alert("该浏览器不支持FileReader对象");
           }
        });
    },
    /**
     * 图片压缩,默认同比例压缩
     * @param {Object} path    
     *         pc端传入的路径可以为相对路径,但是在移动端上必须传入的路径是照相图片储存的绝对路径
     * @param {Object} obj
     *         obj 对象 有 width, height, quality(0-1)
     * @param {Object} callback
     *         回调函数有一个参数,base64的字符串数据
     */
    dealImage :function(path, obj, callback){
        var _this = this;
        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 = obj.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);
                  
            ctx.drawImage(that, 0, 0, w, h);

            //修复图片旋转问题  
            var orientation = _this.option.orientation;
            //如果方向角不为1,都需要进行旋转  
            if(orientation != "" && orientation != 1){ 
                switch(orientation){ 
                    case 6://需要顺时针(向左)90度旋转  
                        _this.rotateImg(that,'left',canvas);  
                        break;  
                    case 8://需要逆时针(向右)90度旋转  
                        _this.rotateImg(that,'right',canvas);  
                        break;  
                    case 3://需要180度旋转  
                        _this.rotateImg(that,'right',canvas);//转两次  
                        _this.rotateImg(that,'right',canvas);  
                        break;
                }         
            } 

            // 图像质量
            if(obj.quality && obj.quality <= 1 && obj.quality > 0){
                quality = obj.quality;
            }
            // quality值越小,所绘制出的图像越模糊
            var base64 = canvas.toDataURL('image/jpeg', quality );
            // 回调函数返回base64的值
            callback(base64);
        }
    },
    rotateImg :function(img,direction,canvas){ //对图片旋转处理
        //最小与最大旋转方向,图片旋转4次后回到原方向    
        var min_step = 0;    
        var max_step = 3;    
        if (img == null)return;    
        //img的高度和宽度不能在img元素隐藏后获取,否则会出错    
        var height = img.height;    
        var width = img.width;    
        var step = 2;    
        if (step == null) {    
            step = min_step;    
        }    
        if (direction == 'right') {    
            step++;    
            //旋转到原位置,即超过最大值    
            step > max_step && (step = min_step);    
        } else {    
            step--;    
            step < min_step && (step = max_step);    
        }    
        //旋转角度以弧度值为参数    
        var degree = step * 90 * Math.PI / 180;    
        var ctx = canvas.getContext('2d');    
        switch (step) {    
            case 0:    
                canvas.width = width;    
                canvas.height = height;    
                ctx.drawImage(img, 0, 0);    
                break;    
            case 1:    
                canvas.width = height;    
                canvas.height = width;    
                ctx.rotate(degree);    
                ctx.drawImage(img, 0, -height);    
                break;    
            case 2:    
                canvas.width = width;    
                canvas.height = height;    
                ctx.rotate(degree);    
                ctx.drawImage(img, -width, -height);    
                break;    
            case 3:    
                canvas.width = height;    
                canvas.height = width;    
                ctx.rotate(degree);    
                ctx.drawImage(img, -width, 0);    
                break;    
        }   
    }

}