美文网首页
js 压缩图片及ajax上传图片

js 压缩图片及ajax上传图片

作者: leoss_H | 来源:发表于2019-01-05 10:56 被阅读0次

最近做的一个微信活动中需要用到图片上传功能,具体就是用户通过手机拍照上传图片来参与活动。在测试的过程中我们发现上传的图片非常大。我们知道现在的手机拍出的图片都非常的大,一般是2~5M,甚至10多M的都有。这么大的图片上传上来,用户的上传体验非常不好,而且给服务器带宽增加了很大的压力,服务器的磁盘空间也会被渐渐撑爆,即使改成上传到oss,也不是很好的办法。于是前端同事就想到先用js压缩图片再上传。我就跟着偷偷学习一下。

js压缩图片

/**
 * js压缩图片
 * @param file 图片文件对象
 * @param quality 压缩倍率 0~1
 * @constructor
 */
function compressImage(file, quality) {

    // 图片小于1M不压缩
    if (file.size < Math.pow(1024, 2)) {
        return file;
    }
    //默认0.5倍压缩
    quality = quality || 0.5;
        
    //保存文件名,后边用到
    var name = file.name; 
    var reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function (e) {
        var src = e.target.result;

        var img = new Image();
        img.src = src;
        img.onload = function (e) {
            var w = img.width;
            var h = img.height;
            //生成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);

            //铺底色 PNG转JPEG时透明区域会变黑色
            ctx.fillStyle = "#fff";
            ctx.fillRect(0, 0, w, h);

            ctx.drawImage(img, 0, 0, w, h);
            // quality值越小,所绘制出的图像越模糊
            var base64 = canvas.toDataURL('image/jpeg', quality); //图片格式jpeg或webp可以选0-1质量区间

            // 返回base64转blob的值
            console.log('\u539F\u56FE' + (src.length / 1024).toFixed(2) + 'kb', '\u65B0\u56FE' + (base64.length / 1024).toFixed(2) + 'kb');
            //去掉url的头,并转换为byte
            var bytes = window.atob(base64.split(',')[1]);
            //处理异常,将ascii码小于0的转换为大于0
            var ab = new ArrayBuffer(bytes.length);
            var ia = new Uint8Array(ab);
            for (var i = 0; i < bytes.length; i++) {
                ia[i] = bytes.charCodeAt(i);
            }
            //通过Blob生成新图片文件对象
            file = new Blob([ab], { type: 'image/jpeg' });
            //这里需要重新设置文件名
            file.name = name;

            return file;
        };
        img.onerror = function (e) {
            console.error(e)
        };
    };
    reader.onerror = function (e) {
       console.error(e)
    };
};

主要用到的原生组件:FileReader、Canvas、Blob、FormData

逻辑步骤:

  1. FileReader.readAsDataURL将上传的图片文件转为Base64格式
  2. 将img绘制到canvas上,canvas.toDataURL压缩图片
  3. new Blob将压缩后的Base64转为Blob格式
  4. FormData.append将图片文件数据存入formdata

注意问题:

  1. PNG转JPEG时PNG格式的透明区域会变黑色,需要先手动铺底色
  2. toDataURL参数为PNG时不支持传图片质量,所以需要写image/jpeg或image/webp,具体可以参考toDataURL的api
  3. 需要先保存文件名,然后生成新的图片后设置文件名为原来的文件名。
  4. formData.append第三个参数filename是有浏览器兼容性问题的,如果不传,图片到后台的文件名会变成blob (filename=blob),后端校验文件名可能过不去。我们就遇到了这个问题。

ajax 上传文件

/**
 * ajax上传文件
 * @param file 文件对象
 */
function upload(file) {
    var formData = new FormData();
    formData.append("file", file, file.name);
    $.ajax({
        url: 'asianCup/uploadBarCode',
        dataType: 'json',
        type: "POST",
        cache: false, 
        contentType: false, //必须
        processData: false, //必须
        data: formData,
        async: true,
        success: function (data) {
            if (data.success) {
                alert("上传成功");
            } else {
                //异常提示
                alert(data.code + "-" + data.msg);
            }
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            console.error(errorThrown);
            if (XMLHttpRequest.responseText.indexOf("400") > -1) {
                //接口或参数出错
                alert("网络不给力,请稍后再试!");
            } else {
                //服务器重启
                alert("网络不给力,请稍后再试!");
            }
        }
    });
}

ajax上传文件需要构建一个formDate对象,将文件appendj进去,然后把formDate对象放到ajax的data参数即可,如果页面本身已经有表单了,也可以直接放到data,并且下面二个参数是必须的:

contentType: false,//必须false才会自动加上正确的Content-Type
processData: false,//必须false才会避开jQuery对 formdata 的默认处理,XMLHttpRequest会对 formdata 进行正确的处理

参考
js压缩图片
ajax上传图片
压缩及上传

相关文章

  • js 压缩图片及ajax上传图片

    最近做的一个微信活动中需要用到图片上传功能,具体就是用户通过手机拍照上传图片来参与活动。在测试的过程中我们发现上传...

  • 表单上传图片(记录)

    项目背景:使用form表单,jQuery的ajax上传图片 获取表单数据,判断图片大小,处理图片,上传表单 压缩图...

  • 图片压缩后上传(压缩工作在前端完成)

    本文只是经# 图片纯前端JS压缩的实现核心代码的简单修改后的多图片上传版本; HTML JS变量及辅助函数 JS核...

  • js图片压缩预览

    图片压缩预览(具体上传请看另外一篇文章,讲解的更详细图片压缩上传) html结构 js代码 css代码 欢迎访问我...

  • js图片压缩上传

    前端有时候会遇到图片太大,预览过慢和无法传给后台的困境,另外还浪费流量。在这里给大家推荐一款配合jQuery运行的...

  • js压缩上传图片

    一、html部分 二、js部分1.获取图片文件 2.利用canvas压缩图片,根据画布大小和图像质量压缩 3.通过...

  • 微信小程序上传图片压缩

    上传图片时图片过大,接口请求速度会很慢,利用canvas对图片进行压缩 wxml文件: js文件:

  • iPic for Mac(图床神器) v1.7.0中文免费版

    上传图片相关设置 上传前压缩图片 可以在 iPic 的 偏好设置 中开启「上传前压缩图片」选项,目前支持压缩的图片...

  • iOS 网络上传图片

    上传图片 构造参数(NSArray *)files 上传图片—压缩 压缩到小于(...

  • Web性能优化

    1、压缩及合并资源使用webpack或Parcel压缩图片、合并CSS和JS文件在线压缩图片网站:https://...

网友评论

      本文标题:js 压缩图片及ajax上传图片

      本文链接:https://www.haomeiwen.com/subject/xmrrrqtx.html