JS 上传图片转换base64字符串&与Blob对象互转&图片下载


一. Image对象转换base64字符串

function imageToBase64Str(img) {

    if (!(img instanceof Image)) {
        throw new Error('请传入Image对象!');
    }

    // 当是站外图片的时候,需要添加允许跨域
    img.setAttribute("crossOrigin", 'Anonymous');

    // 创建canvas对象
    const canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;

    const ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0, img.width, img.height);
    const ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase();
    return canvas.toDataURL("image/" + ext);
}

二. base64字符串转换Blob对象

function base64StrToBlob(base64Str) {

    // 判断是否为base64字符串
    if (!imageUtils.isBase64Str(base64Str)) {
        return;
    }

    const arr = base64Str.split(',');
    const mime = arr[0].match(/:(.*?);/)[1];
    const bstr = atob(arr[1]);
    let n = bstr.length;
    let u8arr = new Uint8Array(n);

    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {
        type: mime
    });
}

三. Blob对象转换为base64字符串

function asyncBlobTobase64Str(blob) {

    if (!(blob instanceof Blob)) {
        throw new Error('请传入Blob对象!');
    }

    // 创建FileReader对象,读取blob为DataURL
    const reader  = new FileReader();
    reader.readAsDataURL(blob);

    return new Promise((resolve, reject) => {
        try {
            // FileReader的onload事件,是要等到文件完全读取完成之后才会执行
            reader.addEventListener("load", (event) => {
                resolve(event);
            });
        } catch (error) {
            reject(error);
        }
    });
}

四. 判断是否为base64字符串

function isBase64Str(validateStr) {

    let base64Str = "";
    try {
        base64Str = validateStr?.split(',')[1];
    } catch {
        return false;
    }

    const pattern = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$/;
    return pattern.test(base64Str);
}

五. 图片下载

/*
    图片下载,支持图片base64字符串和图片url
    参数1: 图片对象
    参数2: 图片名称
*/
async function imageDownload({image, imageName}) {

    if (!(image instanceof Image)) {
        throw new Error('请传入Image对象!');
    }

    // 获取图片url
    let tempSrc = "";
    if (imageUtils.isBase64Str(image.src)) {
        tempSrc = image.src;
    } else {
        /**
         * 如果图片中的url不是base64字符串的,就使用fetch访问,然后获取Blob响应对象
         * 如果不使用fetch的话,还可以使用
         * imageUtils.imageToBase64Str(image对象)的方式得到图片base64字符串
         * 然后使用imageUtils.base64StrToBlob()得到Blob对象
         */
        const response = await fetch(image.src)
        const imgBlob = await response.blob();
        tempSrc = window.URL.createObjectURL(imgBlob);
    }

    // 创建一个隐藏的a标签,并添加到DOM中
    const elink = $('<a>', {
        download: imageName,
        style: "display:none",
        href: tempSrc,
    }).get(0);
    document.body.appendChild(elink);

    // 触发a标签中的点击事件,进行文件下载
    elink.click();

    // 点击之后,移除我们定义的隐藏a标签
    document.body.removeChild(elink);

    // 移除文件对象
    window.URL.revokeObjectURL(tempSrc);
}

六. 图片处理聚合对象

const imageUtils = {
    // Image对象转换base64字符串
    imageToBase64Str,
    // base64字符串转换Blob对象
    base64StrToBlob,
    // Blob对象转换为base64字符串
    asyncBlobTobase64Str,
    // 判断是否为base64字符串
    isBase64Str,
    // 图片下载
    imageDownload
}

// 将其作为模块导出
export default imageUtils;

七. 使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片上传转换</title>
</head>
<body>
    <div>
        <input id="imageFile" type="file" accept="image/png, image/jpg, image/jpeg, image/gif" />

        <!-- 点击图片在新标签页打开 -->
        <a id="aLink" target="_blank">
            <!-- 用来在当前页面展示上传的图片 -->
            <img id="image">
        </a>
        <hr style="margin-bottom: 100px;">

        <img id="cdnImage" src="https://img-blog.csdnimg.cn/1ac4e7e97c4347d59955453b1a230a50.png" alt="">
    </div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script type="module">
    // 导入我们定义的工具类
    import imageUtils from './js/20-图片转换工具类.js';

    // 一秒钟之后,下载图片
    setTimeout(() => {

        const imageInfo = {
        	// jQuery对象转换为原生JSImage对象
            image:  $("#cdnImage").get(0),
            imageName: '下载类测试'
        }
        imageUtils.imageDownload(imageInfo);
    }, 1000);

    // 上传图片之后,将图片转换为base64字符串和dataURL展示在页面上
    $("#imageFile").change(async ({currentTarget: {files}}) => {

		// 读取上传的图片对象
        const file = files[0];
        if (!file) {
            return;
        }

        // 把上传的照片转换为dataURL(base64编码的数据格式,展示类型为字符串)
        const {
            target: {
                result: base64Str
            }
        } = await imageUtils.asyncBlobTobase64Str(file);
        $("#image").attr("src", base64Str);
        
        /*
            接受File或者Blob对象,转换为 dataURL 对象
            把上传的照片转换为 blob:http://localhost:8081/61adf7a6-8b6b-4da9-9e59 这样的格式
        */
        $("#aLink").attr("href", window.URL.createObjectURL(file));

        // 两秒钟之后,把上传的文件下载下来
        setTimeout(() => {

            const imageInfo = {
                // 获取原生image对象
                image: $("#image").get(0),
                imageName: "测试文件"
            }
            
            // 调用工具类方法进行下载
            imageUtils.imageDownload(imageInfo);
        }, 2000);
    });
</script>
</html>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值