图片文件压缩

5 篇文章 0 订阅
2 篇文章 0 订阅

图片文件压缩成指定尺寸并返回base64 格式

1.因业务需求要求前端直接上传base64 图片格式 并大小不能超过2mb
2.网上也有很多相关压缩npm包,直接用对自己技术没啥提升。

然后就手搓了一个压缩图片,代码如下:

/** 
* 符合封闭开放原则
* 封闭FileMethod
* 开放FileExecute
*/

/** 文件方法合集 不用看,不要修改 FileMethod 中的方法 */
class FileMethod {

    /** 
     * @param path 路径转ImageNode
     * @returns Image
     */
    protected static pathShiftImageNode(path: string): Promise<any> {
        return new Promise((resolve, reject) => {
            const img = new Image()
            img.src = path
            img.setAttribute("crossOrigin", 'anonymous')//设置图片跨域属性
            img.onload = (e) => {
                let target = e.target;
                resolve(target)
            }
            img.onerror = reject
        })

    }

    /** 
      * @param file 需要转换的文件
      * @returns [base64,target,node]
      */
    protected static fileShiftBase64(file: File): Promise<any[]> {
        return new Promise((resolve, reject) => {

            const reader = new FileReader()
            reader.readAsDataURL(file)

            function load(node: any) {
                resolve([node?.target?.result, node?.target, node])
            }
            reader.onload = load
            reader.onerror = reject
        })
    }

    /**
     * 
     * @param img img图片元素
     * @param targetWidth  渲染显示出来的目标图片宽
     * @param targetHeight  渲染显示出来的目标图片高
     * @returns canvas 返回canvas元素
     */
    protected static rendererCanvas(img: HTMLImageElement, targetWidth: number, targetHeight: number): HTMLCanvasElement {
        // 创建画布
        const canvas = document.createElement('canvas')
        const context = canvas.getContext('2d');
        // 设置宽高度为等同于要压缩图片的尺寸
        canvas.width = targetWidth;
        canvas.height = targetHeight;
        context?.clearRect(0, 0, targetWidth, targetHeight);
        context?.drawImage(img, 0, 0, targetWidth, targetHeight)
        return canvas
    }


    /** 
        * @param img 根据图片元素动态计算出适合压缩的图片尺寸
        * @returns  { img: HTMLImageElement, targetWidth: number, targetHeight: number }
        */
    protected static ImageFitSize(targetImg: HTMLImageElement, maxWidth = 1000, maxHeight = 1000)
        : { targetImg: HTMLImageElement, targetWidth: number, targetHeight: number } {
        const { width: originWidth, height: originHeight } = targetImg;
        let targetWidth = originWidth;
        let targetHeight = originHeight;
 
        if (originWidth > maxWidth || originHeight > maxHeight) {
            if (originWidth / originHeight > 1) {
                // 宽图片
                targetWidth = maxWidth
                targetHeight = Math.round(maxWidth * (originHeight / originWidth))
            } else {
                // 高图片
                targetHeight = maxHeight
                targetWidth = Math.round(maxHeight * (originWidth / originHeight))
            }
        }
        return { targetImg, targetWidth, targetHeight }
    } 
}


/** 业务执行逻辑  可根据业务需求进行自定义修改  */
class FileExecute extends FileMethod {

    /**
     * @function 压缩图片文件的方法 压缩成指定尺寸大小并返回 base64 格式
     * @describe 图片文件 压缩成指定尺寸大小并返回 base64 格式
     * @param file 需要压缩的图片文件
     * @param {
     * maxWidth = 1000,最大宽
     * maxHeight = 1000,最大高
     * quality = 0.5 ,图片质量,指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的
     * imageType = 'image/jpeg'  
     * } 
     * @returns  { base64 返回压缩后的base64字符串 , canvas  HTMLCanvasElement }  
     */
    static async compressImageFile(file: File, {
        maxWidth = 1000,
        maxHeight = 1000,
        quality = 0.5,
        imageType = 'image/jpeg'
    }): Promise<{ base64: string, canvas: HTMLCanvasElement }> {
        let [base64] = await FileExecute.fileShiftBase64(file)
        let image = await FileExecute.pathShiftImageNode(base64)
        let { targetImg, targetWidth, targetHeight } = FileExecute.ImageFitSize(image, maxWidth, maxHeight)
        //渲染Canvas成指定大小  
        let canvas = FileExecute.rendererCanvas(targetImg, targetWidth, targetHeight)
        //返回原生HTMLCanvas 可根据原生方法 进行自定义
        return { base64: canvas.toDataURL(imageType, quality), canvas: canvas }
    }
}



export default FileExecute

1.根据封闭开放原则 ,封闭FileMethod,开放FileExecute 可根据相关业务修改。

把图片文件压缩成指定尺寸大小

用法:

import { FileExecute } from './fileExecute' 
//示例 imageFile 为图片文件 
const Test = (imageFile)=>{
let { base64, canvas } = await FileExecute.compressImageFile(imageFile,{
		 maxWidth = 1000, //设置最大宽
        maxHeight = 1000,//设置最大高
        quality = 0.5, //设置图片质量 0 ~ 1 
        imageType = 'image/jpeg'//设置图片格式
})
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值