当前位置: 首页 > article >正文

用canvas对图片压缩

用canvas对图片进行压缩

	// 使用canvas对图片进行压缩
	// 创建canvas元素,设置大小,环境
	let canvas = document.createElement('canvas') 
	canvas.width = XXX
	canvas.height = XXX
	let ctx = canvas.getContext('2d') 
	// 绘制图形,参数: 要绘制的图形,画布的起始位置,绘制图形的大小
	ctx.drawImage(image , 0,0,widht ,height) 
	// 压缩图形为base64数据 参数:压缩图片的格式, 图片的质量(0-1)
	let data = canvas.toDataURL('image/png',0.8)

前端获取上传文件内容的方法: new FileReader()

	input.addEventListener('change' , (e) => {
		// input 上传的文件可以在target的files数组中获取到,这里直接结构出来
		const [file] = e.target.files
		let reader = new FileReader()
		// 执行读取文件内容的方法,执行后,reader实例中的result属性就可以获取到文件的base64字符串
		reader.readAsDataURL(file)
		// 成功读取文件后回出发load事件
		reader.onload = (e)=> {
			// 这个e指的是reader实例
			let base64 = e.target.result
			// 定义压缩方法
			compress(base64)
		}
	})

整体代码如下

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <!-- input 上传文件类型,accept限制文件格式 -->
    <input type="file" id="input" accept="image/*">
</body>
<script>
    input.addEventListener('change', (e) => {
        console.log(e)
        const [file] = e.target.files // 获取上传的文件对象
        const reader = new FileReader() // 读取文件数据,这里主要获取的图片的base64编码
        reader.readAsDataURL(file) // 执行此方法后,实例的result中存储当前文件的 base64编码
        // 文件读取完成后触发
        reader.onload = async (e) => {
            const data = e.target.result // 获取base64
            // 绘制原本的图片,和压缩后的做比较
            const _imageCur = new Image()
            _imageCur.src = data

            const base64 = await comapre(data)

            // 绘制压缩后的图片
            const _image = new Image()
            _image.src = base64
            document.body.appendChild(_imageCur)
            document.body.appendChild(_image)
        }
        // 判断并计算图片需要缩放的比例,大小,并借助canvas来压缩图片,canvas.toDataURl()
        async function comapre(base64, maxHeight = 500, maxWeight = 500) {
            const { promise, resolve, reject } = Promise.withResolvers()

            console.log(promise, '29')
            let img = new Image()
            img.src = base64
            img.onload = () => {
                // 调用具体的计算规则方法,返回具体的格式
                let { isNeedCompress, radio, width, height } = getImageComputedSize({
                    isNeedCompress: false,
                    redio: 1,
                    width: img.width,
                    height: img.height,
                    maxHeight,
                    maxWeight
                })

                // 计算后根据isNeedCompress标识字段来判断是否需要改变==== 具体压缩的代码
                if (isNeedCompress) {
                    let canvas = document.createElement('canvas')
                    canvas.width = width
                    canvas.height = height
                    const ctx = canvas.getContext('2d')

                    ctx.drawImage(img, 0, 0, width, height) // 参数:要画的图片对象 , canvas图片的起始坐标,图片的大小
                    const data = canvas.toDataURL('image/png', 0.8) // 调用 canvas.toDataURL()压缩图片,获取的压缩后的base64编码,这里需要用到异步处理
                    resolve(data)
                } else {
                    resolve(base64)
                }
            }
            return promise
        }

        function getImageComputedSize(option) {
            let { isNeedCompress, radio, width, height, maxHeight, maxWeight } = option
            // 根据是横图还是竖图,决定使用长/宽来计算redio

            if (width > height) { // 横图
                if (width > maxWeight) {
                    radio = maxWeight / width
                    height = Math.round(height * radio)
                    width = maxWeight
                    isNeedCompress = true
                }
            } else { // 竖图
                if (height > maxHeight) {
                    radio = maxHeight / height
                    height = maxHeight
                    width = Math.round(width * radio)
                    isNeedCompress = true
                }
            }
            return {
                isNeedCompress, radio, width, height
            }
        }
    })
</script>

</html>

http://www.kler.cn/a/369411.html

相关文章:

  • react 总结+复习+应用加深
  • JVM基础(内存结构)
  • 微信小程序——消息订阅
  • android 文字绘制
  • 前端算法:树(力扣144、94、145、100、104题)
  • STM32 第17章 EXIT--外部中断/事件控制器
  • 遥感图建筑植被道路图像分割系统:逐项优化进阶
  • 数据结构预备知识---Java集合框架、List接口、包装类、装箱拆箱和泛型
  • Linux 中的编译器 GCC 的编译原理和使用详解
  • 租房市场新动力:基于Spring Boot的管理系统
  • TS 基础
  • 【专用名词的离线语音识别在2024年底的解决方法调查-会议签到的补充】
  • 编译,链接。
  • 大数据之实时数据同步方案
  • 香橙派Orangepi 5pro 配置Hailo-8/Hailo-8L
  • 自建html首页
  • 分享electron多窗口实践
  • 使用 NLP 和模式匹配检测、评估和编辑日志中的个人身份信息 - 第 2 部分
  • WPF入门_06资源和样式
  • 在Guided模式下给无人机发送命令设置位置速度
  • 1553B总线电缆网络测试及数据分析设备
  • Linux iptables基本使用
  • RHCE 第二次作业
  • Aloudata BIG 主动元数据平台支持 Oracle/DB2 存储过程算子级血缘解析
  • Django 获取用户IP
  • #Swift The difference between Parameter and Agrument