前端图片压缩,不借助任何第三方api

时间:2021-04-12 12:36:49   收藏:0   阅读:21

前端图片压缩

前置知识点

代码实现

// 使用toBlob
// file,需要压缩的file对象
// quality,压缩的初始质量
// targetSize,需要压缩的临界值,当压缩一次后比这个临界值要大,就自动递归压缩
function compress(file, quality = 0.9, targetSize = 900 * 1024) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = (e) => {
            const src = e.target.result;
            const image = new Image();
            image.src = src;
            image.onload = () => {
                const canvas = document.createElement(‘canvas‘);
                const width = image.width;
                const height = image.height;
                canvas.width = width;
                canvas.height = height;

                const context = canvas.getContext(‘2d‘);
                context.drawImage(image, 0, 0, width, height);

                canvas.toBlob((blob) => { 
                    // 将文件名后缀改成png,并修改文件格式为png格式
                    const miniFile = new File([blob], file.name.replace(/\.[a-zA-Z]+$/g, ‘.png‘), { type: ‘image/png‘ })
                    if(miniFile.size > targetSize) {
                        compress(file, quality * 0.9, targetSize).then(mini => resolve(mini));
                    } else {
                        resolve(miniFile);
                    }
                }, ‘image/jpeg‘, quality);
            }
            image.onerror = (err) => {
                reject(err);
            }
        }
        reader.onerror = (err) => {
            reject(err);
        }
    })
}
// 使用toDateURL
function compress(file, quality = 0.9, targetSize = 900 * 1024) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = (e) => {
            const src = e.target.result;
            const image = new Image();
            image.src = src;
            image.onload = () => {
                const canvas = document.createElement(‘canvas‘);
                const width = image.width;
                const height = image.height;
                canvas.width = width;
                canvas.height = height;

                const context = canvas.getContext(‘2d‘);
                context.drawImage(image, 0, 0, width, height);

                const canvasURL = canvas.toDataURL(‘image/jpeg‘, quality);
                const buffer = atob(canvasURL.split(‘,‘)[1]) // 获取实际的文件内容
                let length = buffer.length
                // 将每一块的内容映射成对应的unicode编码
                const bufferArray = new Uint8Array(new ArrayBuffer(length)).map((item, index) => buffer.charCodeAt(index))
                // 将文件名后缀改成png,并修改文件格式为png格式
                const miniFile = new File([bufferArray], file.name.replace(/\.[a-zA-Z]+$/g, ‘.png‘), { type: ‘image/png‘ })
                if(miniFile.size > targetSize) {
                    compress(file, quality * 0.9, targetSize).then(mini => resolve(mini));
                } else {
                    resolve(miniFile);
                }
            }
            image.onerror = (err) => {
                reject(err);
            }
        }
        reader.onerror = (err) => {
            reject(err);
        }
    })
}
// 调用
compress(file).then(miniFile=> {
  console.log(miniFile);
}).catch(err => {
  console.log(err)
})

注意点

原文:https://www.cnblogs.com/aloneMing/p/14646905.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!