前端实现图片裁剪和压缩

2022-10-26  本文已影响0人  兜兜转转的小菊

前端实现图片的裁剪和压缩
1、压缩图片
drawImage,压缩图片长宽或者质量参数来实现压缩

/**
 * 压缩图片
 * @param {*} src 图片的src
 * @param {*} resolve  回调函数,用于处理异步,比如 promise 返回 
 * @param {*} fileName 文件名称
 */
const compressImage = (src, resolve, fileName = "img") => {
    const image = new Image() // 新建一个img标签(还没嵌入DOM节点)
    image.src = src// 将图片的路径设成file路径
    image.onload = () => {
        const canvas = document.createElement('canvas');
        const context = canvas.getContext('2d');

        // 图片原始尺寸
        const originWidth = image.width;
        const originHeight = image.height;

        // 最大尺寸限制
        const maxWidth = Math.min(image.width, 1200);
        const maxHeight = Math.min(image.height, 1200);
        // 目标尺寸
        let targetWidth = originWidth;
        let targetHeight = originHeight;

        let quality = 0.92; // 默认质量
        // 图片尺寸超过 1200 * 1200 的限制
        if (originWidth > maxWidth || originHeight > maxHeight) {
            if (originWidth / originHeight > maxWidth / maxHeight) {
                // 更宽,按照宽度限定尺寸
                targetWidth = maxWidth;
                targetHeight = Math.round(maxWidth * (originHeight / originWidth));
            } else {
               // 更高,按照高度限定尺寸
                targetHeight = maxHeight;
                targetWidth = Math.round(maxHeight * (originWidth / originHeight));
            }
        }

        canvas.width = targetWidth;
        canvas.height = targetHeight;

        // 绘制图片
        context.drawImage(image, 0, 0, targetWidth, targetHeight);
        // 获取图片url, base64格式
        const data = canvas.toDataURL('image/jpeg', quality);
        // base64格式 转为 file 格式,用于上传
        const newfile = dataURLtoFile(data, `${fileName}.jpeg`);
        resolve(newfile, data);
    }
}

2、图片base64转为file,blob格式

/**
 * base64转file对象
 * @param {*} dataurl 图片base64 数据
 * @param {*} filename 文件名称
 * @returns 
 */
const dataURLtoFile = (dataurl, filename) => {
    const arr = dataurl.split(',');
    const mime = arr[0].match(/:(.*?);/)[1];
    const bstr = atob(arr[1]); let n = bstr.length; const u8arr = new Uint8Array(n);
    // eslint-disable-next-line no-plusplus
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, { type: mime });  // 转成了jpeg格式
}

3、用异步的方式用裁剪图片

    // 裁剪图片
    convertImage = (file) => {
        const that = this;
        return new Promise((resolve) => {
            const image = new Image() // 新建一个img标签(还没嵌入DOM节点)
            image.src = file // 将图片的路径设成file路径
            image.onload = () => {
                const canvas = document.createElement('canvas');
                const context = canvas.getContext('2d');

                const targetWidth = 210; // 裁剪目标宽度 210 px
                const targetHeight = image.height; // 裁剪目标高度 image.height 图片本身高度


                canvas.width = targetWidth; // canvas宽度 210 px
                canvas.height = targetHeight; // canvas宽度 targetHeight

                context.drawImage(image, 115, 0, targetWidth, targetHeight, 0, 0, targetWidth, targetHeight); // 裁剪图片
                const data = canvas.toDataURL('image/jpeg', 1);
                resolve(data);
            }
        })
    }

4、FileReader 读取本地上传的图片文件路径

    readImage = (file) => new Promise((resolve) => {
        // 获取文件名
        const fileName = file.name.substring(0, file.name.indexOf('.'));
        const reader = new FileReader(); // 读取file
        reader.readAsDataURL(file);
        reader.onloadend = (e) => {
            const imgSrc = e.target.result; // 获取文件的src
            // ... 执行后续操作
        }
    })
上一篇下一篇

猜你喜欢

热点阅读