浅谈图片上传及压缩文件

159 阅读2分钟

浅谈图片上传及压缩文件

前言

主要还是因为公司的fastdfs每天上传的图片数量太大导致内存不够,前后端同学都做起来图片压缩工作。

实现思路

思路

  1. 刚开始的想的是用我之前一直用的 熊猫压缩官网 Api压缩发现基本上都是存在于服务端拿取图片请求远程地址然后在保存下来,不打适用于我们这种业务场景。
  2. 网上铺天盖地的提到上传文件转化为canvas将图片的大小(w/h)设为一半,基于这个思路我们写下实现代码。

实现代码

  1. 简单的html代码

    <input accept="image/*" multiple class="file" id="file" type="file" onchange="changepic()" />
  1. 获取文件以及转化文件
    let file = document.getElementById('file');
    let filsval = file.files[0];

变量filsval可以在控制台打印下,他的原型是File对象然后我们继续一层一层进去看发现是blob对象。Blob

将文件对象读取其中的内容转化为Blob流地址,这个地址可以直接赋予img的src,可以直接看图片展示。针对这一点我们可以New一个img对象,将他写入到canvas针对图片的大小进行等比例缩放。针对canvas自身的API将canvas转为toDataURL或者直接转为blob对象。

  1. 贴下完整的代码
    function changepic() {
        let file = document.getElementById('file');
        let reader = new FileReader();
        let filsval = file.files[0];
        
        reader.readAsDataURL(filsval);
        reader.onload = function(e) {
            console.log(e)
            let img = new Image();
            img.src = e.target.result;
            // 完全可以在dom曾创建一个img测试下

            img.onload = () => {
                let canvasUrl = imagetoCanvas(img)
                console.log('canvasUrl++++++', canvasUrl)
                let blobUrl = dataURLToBlob(canvasUrl)
                var formData = new FormData();
                formData.append("files", blobUrl, "image.png");
                $.ajax({
                    type: 'post',
                    url: 'xxxxxxxxxxxxxxxxxxxxxxxxxxx',
                    processData: false,
                    contentType: false,
                    data: formData,
                    success: (res) => {
                        console.log('res+++++', res)
                    }
                })

            }
        }
    }

    function imagetoCanvas(image) {
        var canvas = document.createElement("canvas");
        var ctx = canvas.getContext("2d");
        canvas.width = image.width / 2;
        canvas.height = image.height / 2;
        ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
        return canvas.toDataURL()
    }

    function dataURLToBlob(dataurl) {
        var arr = dataurl.split(',');
        var mime = arr[0].match(/:(.*?);/)[1];
        var bstr = atob(arr[1]);
        var n = bstr.length;
        var u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], {
            type: mime
        });
    }

写在最后

写下此文的真实目的是网上没找到一篇是完整的文章(顺便梳理下对file对象的理解), 上述代码完全能够执行。

重点: 我和服务端的同学测试了下前端的压缩能力太小了,4M只能到3M多,而服务端同学使用JAVA的包 thumbnailator 可以直接压缩到几百K。懂得都懂(手动狗头)

  • 文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞和关注😊