JS/Jquery/Vue使用localResizeIMG插件PC/移动端本地图片压缩

Song1105 次浏览0个评论2022年03月08日

手机端上传图片时,有时候图片会是一张比较大的图片,上传一张的大的图片会消耗比较大的资源影响效率,这个时候就需要对上传的图片进行压缩了。本教程我们使用如下方法来实现。

一、如何安装插件

通过以下方式都可以下载:项目地址 think2011 / localResizeIMG 演示地址:点击查看演示

  1. 执行npm i lrz(推荐)
  2. 或者 git clone本库
  3. 要么 在页面右侧点击download zip

接着在页面中引入

<script src="./dist/lrz.bundle.js"></script>

请绝对不要删除【dist】目录下的任何文件,那些是某些情况自动按需载入的文件。

二、如何使用插件

方法1:监听input变化

如果您的图片来自用户拍摄或者上传的,您需要一个input file来获取图片。

<input onchange="upload()" type="file" capture="camera" />

接着通过change事件可以得到用户选择的图片

function upload () {
    lrz(this.files[0])
        .then(function (rst) {
            // 处理成功会执行
        })
        .catch(function (err) {
            // 处理失败会执行
        })
        .always(function () {
            // 不管是成功失败,都会执行
        });
});

方法2:传入图片路径

如果您的图片不是来自用户上传的,那么也可以直接传入图片路径。

lrz(./xxx/xx/x.png)
        .then(function (rst) {
            // 处理成功会执行
        })
        .catch(function (err){
            // 处理失败会执行
        })
        .always(function () {
            // 不管是成功失败,都会执行
        });

三、后端处理与接收文件

  • 后端最终会收到前端发送的base64字符串,接着处理字符串为图片即可。

  • 具体请使用关键字base64 转 image 开发语言进行谷歌|百度。

  • 前端生成的结果中有一个base64Len,这是字符串的长度,后端应该核对以确认是否提交完整。

四、API

1、参数说明

lrz(file, [options]);


file 通过 input:file 得到的文件,或者直接传入图片路径
[options] 这个参数允许忽略

  • width {Number} 图片最大不超过的宽度,默认为原图宽度,高度不设时会适应宽度。
  • height {Number} 同上
  • quality {Number} 图片压缩质量,取值 0 - 1,默认为0.7
  • fieldName {String} 后端接收的字段名,默认:file

2、返回结果

返回值是一个promise对象
then(rst)
  • rst.formData 后端可处理的数据
  • rst.file 压缩后的file对象(默认已经丢在rst.formData有一份了),需要注意的是如果压缩率太低的话,这个会是原始的file对象
  • rst.fileLen 生成后的图片的大小,后端可以通过此值来校验是否传输完整
  • rst.base64 生成后的图片base64,后端可以处理此字符串为图片,也直接用于img.src = base64
  • rst.base64Len 生成后的base64的大小,后端可以通过此值来校验是否传输完整 (如果采用base64上传方式)
  • rst.origin 也就是原始的file对象,里面存了一些原始文件的信息,例如大小,日期等。
catch(err)
always()


3、JS例子

document.querySelector(input).addEventListener(change, function () {
    // this.files[0] 是用户选择的文件
    lrz(this.files[0], {width: 1024})
        .then(function (rst) {
            // 把处理的好的图片给用户看看呗

            var img = new Image();
            img.src = rst.base64;

            img.onload = function () {
                document.body.appendChild(img);
            };

            return rst;
        })

        .then(function (rst) {
            // 这里该上传给后端啦

            /* ==================================================== */
            // 原生ajax上传代码,所以看起来特别多 ╮(╯_╰)╭,但绝对能用
            // 其他框架,例如jQuery处理formData略有不同,请自行google,baidu。
            var xhr = new XMLHttpRequest();
            xhr.open(POST, http://localhost:5000/);

            xhr.onload = function () {
                if (xhr.status === 200) {
                    // 上传成功
                } else {
                    // 处理其他情况
                }
            };

            xhr.onerror = function () {
                // 处理错误
            };

            xhr.upload.onprogress = function (e) {
                // 上传进度
                var percentComplete = ((e.loaded / e.total) || 0) * 100;
            };

            // 添加参数
            rst.formData.append(fileLen, rst.fileLen);
            rst.formData.append(xxx, 我是其他参数);

            // 触发上传
            xhr.send(rst.formData);
            /* ==================================================== */

            return rst;
        })

        .catch(function (err) {
            // 万一出错了,这里可以捕捉到错误信息
            // 而且以上的then都不会执行

            alert(err);
        })

        .always(function () {
            // 不管是成功失败,这里都会执行
        });
});

4、JQuery 处理例子

例子中给的是原生ajax的方式,下面是JQuery上传的方式

注意!!:使用 zepto 的朋友请用 原生 或 jquery代替,在某些 android 设备下用 zepto 会出现不发送 Content-Type 导致无法上传的BUG。 感谢 @Poised_flw
// 额外添加参数
rst.formData.append(fileLen, rst.fileLen);
 
$.ajax({
    url: http://koa-upload.coding.io, // 这个地址做了跨域处理,可以用于实际调试
    data: rst.formData,
    processData: false,
    contentType: false,
    type: POST,
    success: function (data) {
        alert(JSON.stringify(data));
    }
});


、兼容性

IE9以上及大部分非IE浏览器(chrome、微信什么的)

六、FAQ

有疑问请直接在 issues 中提问 ?

  • Q:有时拍摄完照片后,页面自动刷新或闪退了。

  • A:虽然已作了优化处理,但内存似乎还是爆掉了,常见于低配android手机。

  • Q: 怎么批量上传图片?

  • A: 您可以自己写个循环来传入用户多选的图片,但在移动端上请勿这样做,原因同上。

  • Q: 直接传入图片路径的无法生成图片

  • A: 可能是跨域的问题,具体请看CORS_enabled_image

  • Q: 想要商用可以吗?

  • A: 没问题,但请留意issue里已知的问题。

提交评论

请登录后评论

用户评论

    当前暂无评价,快来发表您的观点吧...

更多相关好文