JS图片压缩和转换字节流

555 阅读1分钟

需求为选择图片上传时需要生成一张封面图与原图一起上传。

几十兆的图片单修改图片清晰度大小压不下来,清晰度太低封面图不忍直视,所以把宽高等比例缩了一下,800是最小宽高,可自调封装。

function compressImg (fileObj, callback) {
    const image = new Image();
    image.src = URL.createObjectURL(fileObj);   
    image.onload = function() {
        const that = this;
        // 等比例压缩宽高    
        let w = that.width;
        let h = that.height;   
        if (w > h) {
            w = 800 * (w / h);
            h = 800;
        } else {       
            h = 800 * (h / w);
            w = 800;
        }    
        // 生成canvas    
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        const anw = document.createAttribute('width');
        anw.nodeValue = w;
        const anh = document.createAttribute('height');
        anh.nodeValue = h;
        canvas.setAttributeNode(anw);
        canvas.setAttributeNode(anh);
        ctx.drawImage(that, 0, 0, w, h);
        const newFile = canvas.toDataURL('image/jpeg', 0.7); // 0.7设置图片质量    
        callback(newFile);
    }
}

下述将base64转为二进制。

function Base64ToBlob (base64) {
    const bytes = window.atob(base64.split(',')[1]); // 去掉url的头,并转换为byte 
    const ab = new ArrayBuffer(bytes.length); // 处理异常,将ascii码小于0的转换为大于0 
    const ia = new Uint8Array(ab);
    for (let i = 0; i < bytes.length; i++) {  
        ia[i] = bytes.charCodeAt(i);
    };
    return new Blob([ab], { type: 'image/png' });
}

下述将blob封装为file对象。

function blobToFile (blob) {
    // 这里的file是我案例里的文件对象。
    // file.name,file.type是文件名称和类型。
    return new window.File([blob], file.name, { type: file.type });
}

下面效果。

仅记录项目中遇到的问题。