用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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值