使用关于图片处理的工具类函数(转base64/压缩/下载)

100 阅读2分钟

blob转为Base64的图片

  • blob 二进制文件流
  • blobType MIME类型
  • return Base64格式的字符串
export function blobToBase64(blob: Blob, blobType?:string):Promise<ArrayBuffer | string | null>{
    return promise((resolve, reject) => {
        let blobInstance = null
        if(!blobType) blobInstance = blob //如果没有设置MIME类型,就默认赋值
        else blobInstance = new Blob([blob], {type: blobType})
        
        const render = new FileReader()
        render.readAsDataURL(blobInstance)
        render.onload = () => resolve(render.result)
        render.onerror = error => reject(error)
}

压缩File类型的图片

  • file: File类型的图片
  • maxW: 最大的图片宽度
  • quality 图片质量(0-1, 数值越低,图片越模糊)
  • return Base64格式的字符串
export async function compressImg(file: File, maxW = 400, quality = 0.2): Promise<string>{
    const result: any = await blobToBase64(file) //先转为base64的文件字符串
    //获取文件大小,Number(), + 都是强转为数字类型的值,然后toFixed(4)四舍五入后4位小数点
    const fileSize = +(Number(file['size']) / 1024 / 1024).toFixed(4) 
    
    const image = new Image()
    image.src = result
    return new Promise(resolve => {
        //图片加载完毕后再通过canvas压缩图片,还没加载完就压缩会导致图片全是黑的
        image.onload = () => {
            const maxWidth = maxW
            const originWidth = image.width //获取图片原本的宽度
            const originHeight = image.height //获取图片原本的高度
            
            let targetWidth = originWidth
            let targetHeight = originHeight
            
            //原始尺寸 > 限定尺寸
            if(originWidth > maxWidth){
                targetWidth = maxWidth //目标宽度 = 限定宽度
                //目标高度=目标宽度/原本宽度之比再乘原高,即原本高度等比例增高
                //Math.round()四舍五入到最接近的整数值,小数部分<0.5 向下取整,else向上
                targetHeight = Math.round(maxWidth * (originHeight / originWidth))
            }
            
            const canvas = document.createElement('canvas')
            const context = canvas.getContext('2d')! //非空断言,创建2d画布
            
            let compressedBase64 = ''  //压缩后的图片
            canvas.width = targetWidth
            canvas.height = targetHeight
            context.drawImage(image, 0, 0, targetWidth, targetHeight)
            
            //使用toDataURL()将canvas上的图片转换位Base64格式
            if(fileSize < 1) compressedBase64 = canvas.toDataToURL(file['type'], 0.6)
            else compressedBase64 = canvas.toDataURL(file['type'], quality)
            resolve(compressedBase64)
        }
    })
}

下载二进制文件流

  • blob 文件流
  • name 文件名(需携带后缀)
export function download(blob: Blob, name: string): void{
    if(blob?.type === 'application/json'){
        msgError('导出失败')
        throw new TypeError('文件类型错误')
    }
    
    const a = document.createElement('a') //动态创建a链接
    a.href = URL.createObjectURL(blob) //创建文件资源流
    a.download = name
    a.click()
    URL.resolveObjectURL(a.href)  //释放内存
}