canvas图片压缩!

212 阅读2分钟

canvas and svg

canvas是一个可以使用js脚本来绘制图形的HTML元素,它是chrome为我们提供好的一个绘制2D图形的api.
svg是使用XML标签来绘制2D图形的语言,和canvas最大的写法上的区别就是:
(1).svg的写法和编写html标签一样,而canvas则需要使用js;
(2).canvas 是在规定的画布上面逐像素进行渲染的,当我们在浏览器开发者工具对其进行选中时,是不能选中的;
(3).canvas是依赖分辨率是位图,svg不依赖分辨率是可缩放矢量图形;
(4).canvas比较适用在动画、游戏或者需要大量密集图像中,svg因为是渲染在dom中,所以不适合大量使用,不适合游戏应用,一般比较适合做一些icon适用。

编写区别

canvas

  • 编写canvas标签
	<canvas id="canvas" width="800" height="800"></canvas>
  • 获取cancvas dom对象
 	const canvas = document.getElementById('canvas')
  • 获取cancvas 对象
	const ctx = canvas.getContext('2d')
  • 设置绘图属性,调用绘图api
//绘制矩形
        ctx.fillStyle = 'red'
        ctx.fillRect(0,0,50,50)
//绘制线段
        ctx.beginPath()
        ctx.lineWidth = 3
        ctx.strokeStyle = 'blue'
        ctx.moveTo(500, 100)
        ctx.lineTo(600, 200)
        ctx.lineTo(800, 100)
        ctx.lineTo(500, 100)
        ctx.stroke()
        
 //绘制圆形
        ctx.beginPath()


        ctx.lineWidth = 2
        ctx.strokeStyle = 'green'
        ctx.fillStyle = 'red'
        ctx.arc(200,200,50,0,2*Math.PI)
        ctx.stroke()
        ctx.fill()

//绘制点
        ctx.beginPath()
        ctx.lineWidth = 1
        ctx.strokeStyle = 'blue'
        ctx.moveTo(400, 400)
        ctx.lineTo(401, 401)
        ctx.stroke()

svg

和书编写html标签一样

  • 编写一个svg 容器
<svg width="800" height="800"></svg>
  • 绘制矩形
<svg width="800" height="800">
  <rect
            width="50"
            height="50"
            style="fill: red;"
        >
        </rect>
    </svg>
      
  • 绘制圆,其中设置图形的样式,可以是属性的方式,也可以现在style里面
<svg width="800" height="800">
	<circle
            cx="200"
            cy="200"
            r="50"
            stroke="green"
            style="stroke-width: 2;fill: red;"
        >

        </circle>
  </svg>

canvas实际使用场景

图片压缩

前端图片压缩,已经有现成的api可以调用,主要还是通过canvas的drawImage api 把图片绘制在规定大小的画布上。

  • 上传图片时,通过调用new FileReader(),获取图片的base64资源
	upload.addEventListener('change', function(e) {
            const [ file ] = e.target.files
            if (!file) return

            const {type:fileType, size: fileSize} = file
            if ( ACCEPT.indexOf(fileType) < 0 ) {
                upload.value = ''
                return alert('类型不支持')
            }
            if ( fileSize > MAXSIZE ) {
                upload.value = ''
                 alert(`文件大小超出${MAXSIZE_STR}`)
                return
            }
            //图片压缩
            //1.将图片转为base64
            converImageToBase64(file, compress)
            
        })
function converImageToBase64(file, callback) {
            let reader = new FileReader()
            reader.addEventListener('load', function(e) {
                const base64Img = e.target.result
                callback && callback(base64Img)
                reader = null
            })
            reader.readAsDataURL(file)
        }
  • 图片压缩核心 drawImage
function compress(base64Img, callback) {
            let maxW = 400 // 最大宽
            let maxH = 400 // 最大高
            const image = new Image()
            image.addEventListener('load', function(e) {
                let ratio; //图片压缩比
                let needCompress = false //是否需要压缩
                if (maxW < image.naturalWidth) { 
                //如果上传图片的宽大于限制的宽度,那么需要压缩,用图片的宽度 / 最大的宽度
                此时 maxW = 400,maxH也等比例缩放ratio
                    needCompress = true
                    ratio = image.naturalWidth / maxW
                    maxH = image.naturalHeight / ratio
                }
                if (maxH < image.naturalHeight) {
                //图片高度比maxH大
                    needCompress = true
                    ratio = image.naturalHeight / maxH
                    maxW = image.naturalWidth / ratio
                }

                if (!needCompress) { //如果不需要压缩,也就是上传的图片宽高在限制的范围内,就用图片的原始宽高
                    maxW = image.naturalWidth
                    maxH = image.naturalHeight
                }
                const canvas = document.createElement('canvas')
                canvas.setAttribute("id", "canvas")
                canvas.width = maxW
                canvas.height = maxH
                canvas.style.display = 'none'
                document.body.appendChild(canvas)

                const ctx = canvas.getContext('2d')
                ctx.clearRect(0,0,maxW, maxH)
                ctx.drawImage(image, 0, 0, maxW, maxH)
                const compressImage = canvas.toDataURL('image/jpeg', 0.8)
                callback && callback(compressImage)
                canvas.remove()
            })
            image.src = base64Img
            document.body.appendChild(image)
        }