基于Plupload的图片压缩上传

版权声明:本文为博主原创,转载加个原文章链接。 https://blog.csdn.net/xiaolongbaobushibao/article/details/79407242

前言

这里的上传工具基于JQuery、Plupload

传送门:Plupload官方中文文档

  • 为什么要做图片压缩?
    现在手机拍照都快10M了,但是有时候图片上传只要看得清楚就可以了,比如上传身份证200k能看清楚,为什么要上传20M?这样做的好处是减少服务器存储压力、减少带宽占用。

  • 为什么要自己做一个压缩图片的?
    官方有提供压缩方式:

resize: {
  width: 100,//指定压缩后图片的宽度,如果没有设置该属性则默认为原始图片的宽度
  height: 100,//指定压缩后图片的高度,如果没有设置该属性则默认为原始图片的高度
  crop: true,//是否裁剪图片
  quality: 60,//压缩后图片的质量,只对jpg格式的图片有效,默认为90。quality可以跟width和height一起使用,但也可以单独使用,单独使用时,压缩后图片的宽高不会变化,但由于质量降低了,所以体积也会变小
  preserve_headers: false//压缩后是否保留图片的元数据,true为保留,false为不保留,默认为true。删除图片的元数据能使图片的体积减小一点点
}

这边作为Plupload初始化参数传递进入,如果这样做,无论是10M的图片还是10K的图片。都会被压缩。
所以我这边做一个demo来压缩到指定大小的工具。

正文

1、引用

这里的demo没有使用模块化前端工程,只是简单的Script 引入

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
    <script src="./plupload-2.3.1/js/moxie.js"></script>
    <script src="./plupload-2.3.1/js/plupload.dev.js"></script>
    <script src="./reduce-image-uploader.js"></script>
    <script src="./index.js"></script>
    <title>Title</title>
</head>
<body>
图片压缩上传测试按钮
<button id="upload-btn"> 上传</button>
</body>
</html>

注意: 引用必须按照顺序,后面的会依赖前面的
- 为什么引用plupload.dev.js,而不是其他的。好像是因为plupload.full.min.js内部引用了moxie还是什么的,直接用这个会报错。
- moxie 压缩专用
- plupload 上传专用
- reduce-image-uploader 自己的小工具
- index.js 小工具使用

2、工具

  • 工具代码:
var uploadTool = (function () {
    var uploader;
    var option = {};
    /**
     * 初始化方法,需要传入配置信息。!开头为必填
     * @param option{
     *      !up:dom节点ID或者dom节点,如upload-id 或者 document.getElementById("upload-id")或者 $("#upload-id")[0]
     *      !successCb:成功的回调,接收一个服务器返回对象successCb(responseObj),如responseObj:{data:"20180227/3fc1d47f951d254ae8b8f9a8b8be1aee.jpg",msg:"上传成功",status:true}
     *      failCb:失败的回调
     *      !url:图片上传的路径
     *      maxSelectIeSize:"10kb",//IE8及以下的能选中最大的图片
     *      maxSelectSize:"8000kb",//其他浏览器能选中最大的图片
     *      maxFileSize:200//单位kb,默认压缩到200k以下的再上传,可以修改这个上限
     * }
     * @returns {plupload.Uploader}
     */
    var init = function (opt) {
        var defaultOption = {
            url:"XXXXXX.do",
            successCb:function (msg) {console.log(msg)},
            failCb:function (msg) {console.log(msg)},
            maxSelectIeSize:"1500kb",
            maxSelectSize:"8000kb",
            maxFileSize:200,//压缩后的大小,单位kb
        }
        option = $.extend({},opt,defaultOption);
        uploader = new plupload.Uploader({
            runtimes : 'html5,flash,silverlight,html4',//压缩使用的运行环境
            browse_button : option.up, // 绑定的上传按钮,注意IE9以下的如果为隐藏的节点,会失效。在非隐藏的情况下使用 uploader.refresh()激活
            multi_selection:false,//这个工具不支持多选
            url : option.url,//url地址,必填。
            multipart : true,
            filters : {//过滤器
                mime_types : [
                    { title : "Image files", extensions : "jpg,png,jpeg,JPG,PNG,JPEG" }
                ],
                max_file_size:!$.support.leadingWhitespace? option.maxSelectIeSize:option.maxSelectSize,//IE 8以下的限制大小为1500kb,其他情况下为
            },
            init: {//初始化
                PostInit: function() {
                },

                FilesAdded: function(up, files) {//单选,选中文件后立即执行压缩,如果压缩成功会直接上传
                    //这边只在文件添加的时候压缩。压缩后会移除掉文件,然后再次触发压缩的功能,知道符合标准直接上传
                    downSizeImage(uploader,files).fail(option.failCb);
                },
                UploadProgress: function(up, file) {
                    // console.log("上传的进度"+file.percent +"%")
                },
                FileUploaded:function(uploader,file,responseObject){
                    solutions(responseObject,option.successCb,option.failCb)
                },
                Error: function(up, err) {
                    solutions(err,option.successCb,option.failCb)
                }
            }
        });
        uploader.init();
        return uploader;
    }
    /**
     * 压缩工具:
     * @param uploader
     * @param files
     * @returns {*}
     */
    var downSizeImage= function (uploader,files) {
        var $def = $.Deferred();
        uploader.stop();
        var imageMaxSize  = option.maxFileSize * 1024;//不处理的图片大小阀值B
        var maxResizeTime  = 10;//最大压缩次数
        var file = files[0];
        if(!$.support.leadingWhitespace){//IE6-8的情况不压缩直接上传
            console.info("IE6-8的情况不压缩直接上传")
            uploader.start()
            return $def.resolve({})
        }
        if(file.size <= imageMaxSize){//图片在限制之内则直接上传
            console.info("图片大小为:"+file.size+"b,开始上传")
            uploader.start()
            return $def.resolve({})
        }
        if(file.resizeTime == undefined){//如果没有压缩过,则初始压缩次数为0
            file.resizeTime = 0
        }
        file.resizeTime ++ ;
        if(file.resizeTime >=  maxResizeTime){//如果超出压缩最大次数,那么直接提交,交给后台拦截,常见Png。如果一个图片一直压缩不了,那么不限制次数,浏览器会炸的
            console.info("压缩次数达到极限,不能再压缩了,直接上传")
            uploader.start()
            return $def.resolve({})
        }
        var mOxieLoader = new moxie.image.Image();
        mOxieLoader.onload = function () {
            var scare = Math.sqrt(imageMaxSize /mOxieLoader.size)//压缩率
            var opts = {//其实只有width 和height有用
                width : mOxieLoader.width * scare,
                height : mOxieLoader.height * scare,
                imageType:mOxieLoader.type,
                size:mOxieLoader.size
            }
            console.log("开始压缩!当前图片大小为:",opts.size,"b")
            mOxieLoader.downsize(opts);
            var newFile = mOxieLoader.getAsBlob(opts.imageType);
            newFile.resizeTime = file.resizeTime;
            $.each(uploader.files,function(i,v){//清除原先的上传队列
                uploader.removeFile(uploader.files[0].id)
            })
            uploader.addFile(newFile)//回炉重造
        }
        mOxieLoader.onerror = function () {
            console.log(arguments)
            $def.reject({msg:"文件压缩出现错误,请上传小于1M的图片"})
        }
        mOxieLoader.load(file.getSource());
        return $def;
    }
    var getResponseObj = function (responseObject) {//获取Response的结果对象
        //TODO 这边可能会有错误码 需要处理
        var res = {msg:"未知错误"}
        if(!responseObject || !responseObject.response){
            return res
        }
        try {
            res = JSON.parse(responseObject.response)
        }catch (e){
            console.error(e)
        }
        return res
    }
    /**
     * 处理程序
     * @param responseObject
     * @param successCb
     * @param failCb
     */
    var solutions = function(responseObject,successCb,failCb){//成功失败的处理方式
        var responseObj = getResponseObj(responseObject);
        if(responseObj.status){
            successCb(responseObj)
        }else{
            failCb(responseObj)
        }
    }
    /**
     * 刷新
     */
    var refresh = function () {
        uploader.refresh()
    }
    return {
        init:init,
        refresh:refresh
    }
})()
  • 使用方式:
$(function () {
    uploadTool.init({up:"upload-btn",maxFileSize:100})
})

3 坑爹

  • plupload对IE89隐藏模式下的标签绑定或者初始化有问题。

解决方案:想办法让这个绑定的标签显示出来或者用层级样式让其他标签覆盖这个标签。

uploader = new plupload.Uploader(config);
uploader.init();
//显示之后再去调用refresh
uploader.refresh();
  • 坑爹的IE对H5支持不是很好,浏览器连图片大小都识别不出来,你要我怎么办?只能直接上传咯

4 demo下载

http://download.csdn.net/download/xiaolongbaobushibao/10264085

猜你喜欢

转载自blog.csdn.net/xiaolongbaobushibao/article/details/79407242