imgurl-base64.ts 4.2 KB
Newer Older
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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126

import axios from 'axios';

export class ImgurlBase64{
    /**
     * 单例变量声明
     *
     * @memberof ImgurlBase64
     */
    private static imgurlBase64: ImgurlBase64;

    /**
     * 图片缓存(加载中)
     *
     * @type {Map<string,any>}
     * @memberof ImgurlBase64
     */
     public static imgCache: Map<string, any> = new Map();

     /**
      * 图片缓存(已完成)
      *
      * @type {Map<string,any>}
      * @memberof ImgurlBase64
      */
     public static imgCached: Map<string, any> = new Map();

    /**
     * 获取 ImgurlBase64 单例对象
     *
     * @memberof ImgurlBase64
     */
     public static getInstance() {
        if (!this.imgurlBase64) {
            this.imgurlBase64 = new ImgurlBase64();
        }
        return this.imgurlBase64;
    }

    /**
     * 手动获取图片
     * 
     * 
     * @param url 图片url路径
     * @returns 
     */
    public async getImgURLOfBase64(url: string) {
        return new Promise((resolve, reject) => {
            let img = '/';
            // 富文本CV上传图片与鼠标移出抛值冲突问题,上传成功回调还没执行时就抛值
            var reg = /^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s]*?)\s*$/i;
            if (reg.test(url)) {
                return resolve(url);
            }
            // 缓存中有从缓存中拿
            if (ImgurlBase64.imgCached.get(url)) {
                let img = ImgurlBase64.imgCached.get(url);
                resolve(img);
            }
            const callback: Function = (url: string, promise: Promise<any>) => {
                promise.then((response: any) => {
                    if (response && response.status === 200 && response.data) {
                        // 获取文件名
                        const disposition = response.headers['content-disposition'];
                        const filename = disposition.split('filename=')[1];
                        let type = 'image/png';
                        if (filename && filename.indexOf('.') > 0) {
                            const start = filename.lastIndexOf('.');
                            const expandedName = filename.substring(start + 1);
                            if (expandedName.match(/(bmp|jpg|jpeg|png|tif|gif|pcx|tga|exif|fpx|svg|psd|cdr|pcd|dxf|ufo|eps|ai|raw|WMF|webp)/gi) != null) {
                                type = 'image/' + expandedName;
                            } else {
                                resolve(img);
                            }
                        }
                        let blob = new Blob([response.data],{type: type});
                        this.blobToBase64(blob).then((res) => {
                            // 转化后的base64
                            img = `${res}`;
                            // 缓存图片
                            ImgurlBase64.imgCached.set(url, img);
                            resolve(img);
                        })
                    } else {
                        resolve(img);
                    }
                }).catch((result: any) => {
                    return resolve(img);
                })
            }
            // 加载中
            if (ImgurlBase64.imgCache.get(url)) {
                callback(url, ImgurlBase64.imgCache.get(url));
            } else {
                let _url = url;
                if (!Object.is('/', _url.substring(0,1))) {
                    _url = '/'+_url;
                }
                let result:Promise<any> = axios({method: 'get', url: _url, responseType: 'blob'});
                ImgurlBase64.imgCache.set(url, result);
                callback(url, result);
            }
        });
    }

    /**
     * 将blob转为base64
     * 
     * 
     * @param blob blob对象
     * @returns 
     */
    public blobToBase64(blob: any) {
        return new Promise((resolve, reject) => {
            const fileReader = new FileReader();
            fileReader.onload = (e: any) => {
                resolve(e.target.result);
            };
            // readAsDataURL
            fileReader.readAsDataURL(blob);
            fileReader.onerror = () => {
                reject(new Error('blobToBase64 error'));
            };
        });
    }
}