图片压缩

前端图片压缩

前几天做项目,由于要上传大量的扫描图片,为了加快上传速度,就自然而然的想到了图片压缩,最近有了点时间就整理了下代码,贴出来以备后用。

在压缩图片的过程中主要使用了FileReader 、canvas、以及base64长度的计算,整个功能的思路并不复杂,实现过程大致如下:

(1) 用户上传的时候通过input  onchange事件拿到file对象,然后把file对象通过  FileReader转成base64字符串

(2)新建img对象 把数据赋值到img对象

(3)新建canvas对象 用canvas.toDataURL() 实现压缩

代码并不复杂,但是还是小小的踩了几个坑的,详细代码如下:

 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>图片转base64</title>
</head>

<body>
    <input type="file" id="file">
    <img src="" id="testimg" alt="">
</body>


<script>
    document.getElementById('file').onchange = function(e) {
        var file = e.target.files[0];
        toBase64(file)
    }

    function toBase64(file) {
        var name = file.name //文件名
        var size = file.size //文件的字节大小。
        var type = file.type //字符串类型,文件的MIME类型。
        var reader = new FileReader(); //reader对象
        var imgurl = '';
        reader.readAsDataURL(file); //并将文件数据以URL形式保存到result属性中
        reader.onloadend = function(e) {
            imgurl = e.target.result; //base64字符串
            canvasDataUrl(imgurl, file, 1000, 800 * 1024, objDiv) //压缩图片
        }
    }

    function objDiv(base64) {
        document.getElementById('testimg').src = base64;

    }

    function computedSize(base64Str) { //计算base64字符串字节大小
        base64 = base64Str.split(',')[1]; //去掉前缀
        base64.replace(/=/g, ''); //去除=
        var length = base64.length;
        return length - length / 8 * 2;
    }

    function canvasDataUrl(imgurl, file, maxPixeSize, maxBateSize, callback) {
        // imgurl:原图片runder之后得base64;file: 原图片file对象, maxPixeSize:压缩图片后最大像素尺寸, maxBateSize//压缩后输出的最大字节
        var img = new Image();
        if (computedSize(imgurl) < maxBateSize) {
            callback.call(null, imgurl);
            return;
        }
        console.log('压缩前大小:' + file.size)
        img.src = imgurl;
        img.onload = function() {
            var that = this;
            var w = that.width,
                h = that.height,
                scale = w / h; //宽高比
            var quality = 1;
            var canvas = document.createElement('canvas');
            var max_Szie = Math.max(w, h);
            //尺寸压缩
            if (max_Szie > maxPixeSize) { //计算比例
                quality = maxPixeSize / max_Szie
            }
            var new_width = w * quality;
            var new_height = h * quality;
            canvas.width = new_width;
            canvas.height = new_height;
            var ctx = canvas.getContext('2d');
            ctx.clearRect(0, 0, new_width, new_height)
            ctx.drawImage(that, 0, 0, new_width, new_height);
            var arr = imgurl.split(',');
            var mine = arr[0].match(/:(.*?);/)[1]; //文件类型 :image/jpeg jpg为例
            var base64UrlPrefix = arr[0] + ','; //data:image/jpeg;base64, jpg为例
            var Ratio = 0.9; //压缩比率
            if (computedSize(imgurl) > 1024 * 1024) {
                Ratio = 0.6;
            }
            jpegURL = canvas.toDataURL(mine, Ratio).replace(/^.*?,/, ''); //只保留字符串部分

            if (window.atob(jpegURL).length > maxBateSize) {
                Ratio = 0.3;
                jpegURL = canvas.toDataURL(mine, Ratio).replace(/^.*?,/, '');
            }
            img = null;
            canvas = null;
            if (typeof callback == 'function') {
                // 回调函数返回base64的值
                callbackurl = base64UrlPrefix + jpegURL;
                callback.call(null, callbackurl); //参数压缩后的base64
            }

        }
    }
</script>

</html> 

学如逆水行舟,不进则退!

与诸君共勉!

原文地址:https://www.cnblogs.com/Black-Skin/p/10788938.html