haizlin / fe-interview

前端面试每日 3+1,以面试题来驱动学习,提倡每日学习与思考,每天进步一点!每天早上5点纯手工发布面试题(死磕自己,愉悦大家),6000+道前端面试题全面覆盖,HTML/CSS/JavaScript/Vue/React/Nodejs/TypeScript/ECMAScritpt/Webpack/Jquery/小程序/软技能……
http://www.h-camel.com
MIT License
25.42k stars 3.26k forks source link

[html] 第329天 如何使用html5进行图片压缩上传? #2033

Open haizhilin2013 opened 4 years ago

haizhilin2013 commented 4 years ago

第329天 如何使用html5进行图片压缩上传?

我也要出题

chisfee commented 4 years ago

涉及到H5图片压缩,第一应该想到的是canvas的图片处理api。 先利用canvas.toDataURL('"image/jpeg",quality)中的quality参数进行图片压缩范围是0~1之间,再将图片base64格式转化为blob对象,最后使用formData和正常图片上传流程一样。

lincimy commented 4 years ago

1.获取到图片的base64格式; 2.图片加载完成后,把图片转化为canvas; 3.使用canvas的toDataURL按照自己的需要进行压缩; 4.把dataURL转化成blob对象; 5.把blob对象转化成formData对象,最后按照ajax接口调用方式提交;

webVueBlog commented 4 years ago

H5:进行图片压缩上传

<canvas canvas-id='attendCanvasId' class='myCanvas' :style="'width:' + imageSize.imageWidth + 'px; height:' + imageSize.imageHeight  + 'px;'"></canvas>

imageSize: '',

压缩代码:

// 压缩图片
paressImage: function(image, fn) {
    let img = new Image()
    // 要给对象图片的路径
    img.src = image.path
    let canvas = document.createElement('canvas');
    let ctx = canvas.getContext('2d')
    // 最大尺寸限制
    var maxWidth = 500,
        maxHeight = 500;
    var canvasWidth, canvasHeight;
    // 取得压缩后得高宽
    if (image.width > image.height) {
        if (image.width > maxWidth) {
            canvasWidth = maxWidth;
            canvasHeight = image.height * (canvasWidth / image.width)
        } else {
            canvasWidth = image.width;
            canvasHeight = image.height;
        }
    } else {
        if (image.height > maxHeight) {
            canvasHeight = maxHeight;
            canvasWidth = image.width * (canvasHeight / image.height);
        } else {
            canvasWidth = image.width;
            canvasHeight = image.height;
        }
    }
    canvas.width = canvasWidth
    canvas.height = canvasHeight
    // 图片画在画布上
    ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight)
    // 图片资源
    canvas.toBlob((fileSrc) => {
        console.log('fileSrc', fileSrc)
        var imgSrc = window.URL.createObjectURL(fileSrc)
        fn(imgSrc);
    }, 'image/png', 0.50);

},

图片上传:

uploadFile

url: this.$store.state.baseUrl + '/manage/upload/upload_file',
filePath: imgSrc,
fileType: 'image',
name: 'file',
...
var obj = JSON.parse(uploadFileRes.data)
this.query.image = obj.data.img_url
longhui520 commented 4 years ago
    function photoCompress(file,options, callback) {
        var ready = new FileReader();
        ready.readAsDataURL(file);
        ready.onload = function () {
            var base64Url = this.result;
            canvasDataURL(base64Url, options, callback)
        }
     }
     //options可以是设置压缩后的图片的宽高或者压缩比例
     function canvasDataURL(base64Url, options, callback) {
        var img = new Image();
        img.src = base64Url;
        img.onload = function () {
            var that = this;
            // 默认按比例压缩
            var w = that.width,
                h = that.height,
                scale = w / h;
            w = options.width || w;
            h = options.height || (w / scale);
            var quality = 0.7; // 默认图片质量为0.7
            //生成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);
            ctx.drawImage(that, 0, 0, w, h);
            // 图像质量
            if (options.quality && options.quality <= 1 && options.quality > 0) {
                quality = options.quality;
            }
            // quality值越小,所绘制出的图像越模糊
            var base64 = canvas.toDataURL('image/jpeg', quality);
            // 回调函数返回base64的值
            callback(base64);
        }
        function convertBase64UrlToBlob(urlData) {
            var arr = urlData.split(','),
                mime = arr[0].match(/:(.*?);/)[1],
                bstr = atob(arr[1]),
                n = bstr.length,
                u8arr = new Uint8Array(n);
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new Blob([u8arr], {
                type: mime
            });
        }
        photoCompress(file,{quality:0.1},function(base64Codes){
            var bob = convertBase64UrlToBlob(base64Codes);
            //修改文件名或上传
        })
        //1. 获取到文件对象,转成base64URL,
        //2. 根据base64URL 获取到图片的宽高,生成canvans
        //3. canvans 对象根据压缩比例,生成base64URL
        //4. base64URL生成blob对象