• 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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    二. 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
        });
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    三. 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);
            }
        });
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    四. 判断是否为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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    五. 图片下载

    /*
        图片下载,支持图片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 = $('', {
            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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    七. 使用

    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
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
  • 相关阅读:
    优先级队列(堆)——小记
    编译工具:CMake(七) | cmake 常用变量和常用环境变量
    SpringBoot结合Liquibase实现数据库变更管理
    QQ空间里面的照片变模糊了怎么办?时间越久越模糊怎么修复清晰?
    机器学习(三):多项式回归
    Hierarchy-Aware Global Model for Hierarchical Text Classification
    Emmet语法
    【Java】人工智能交互智慧导诊系统源码
    【Git】在 Raspberry PI 上部署 Gogs
    26、Nerfies:Deformable Neural Radiance Fields
  • 原文地址:https://blog.csdn.net/feyehong/article/details/126449848