通过canvas获取图片base64位编码

 2022-01-07 

前言

canvas是HTML5提供的一种2D绘图工具,官方库中提供了各种可以绘制直线、矩形、多边形等形状的API。在前端和后端的交互中,后端往往需要在前端获取图片的base64位编码信息,而canvas提供了getImageData和toDataURL等接口,使前端能够方便地获取图片信息。

在canvas显示本地图片

在HTML中通过canvas标签能够在div上面设置一块画布,并设置其宽度和高度,然后将图片放置在上面即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>在canvas上显示图片</title>
</head>
<body>
    <div>
        <canvas id="origin_canvas"></canvas>
    </div>
    <script>
        // 获取canvas元素
        let canvas = document.getElementById('origin_canvas')
        // 获取canvas的上下文信息
        let ctx = canvas.getContext('2d')
        // 新建Image对象
        let image = new Image()
        image.src = './images/test.png'
        image.onload = function () {<!-- -->
            // 设置canvas的宽和高
            canvas.width = image.width
            canvas.height = image.height
            // 将图片绘制到canvas上
            ctx.drawImage(image, 0, 0, image.width, image.height)
        }
    </script>
</body>
</html>

在canvas上获取特定位置的base64信息

在DOM节点上在创建一个新的canvas元素,然后将矩形框内的图片信息放入该canvas中,最后通过toDataURL API即可获取矩形区域内的base64位编码信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>在canvas上面获取特定位置的base64信息</title>
</head>
<body>
    <div>
        <canvas id="origin_canvas"></canvas>
    </div>
    <script>
        // 获取canvas元素
        let canvas = document.getElementById('origin_canvas')
        // 获取canvas的上下文信息
        let ctx = canvas.getContext('2d')
        // 新建Image对象
        let image = new Image()
        image.src = './images/test.png'
        image.onload = function () {<!-- -->
            // 设置canvas的宽和高
            canvas.width = image.width
            canvas.height = image.height
            // 将图片绘制到canvas上
            ctx.drawImage(image, 0, 0, image.width, image.height)

            // 获取50,50 到 200,200矩形区域的base64信息
            let base64Info = getImageBase64Data()
            console.log(base64Info)
        }
        function getImageBase64Data() {<!-- -->
            let cropImgInfo = ctx.getImageData(50, 50, 150, 150)
            let newCanvas = document.createElement('canvas')
            newCanvas.width = 200 - 50
            newCanvas.height = 200 - 50
            let newCtx = newCanvas.getContext('2d')
            newCtx.putImageData(cropImgInfo, 0, 0)
            return newCanvas.toDataURL()
        }
    </script>
</body>
</html>

在canvas上显示跨域的图片资源

有时候前端使用的图片资源并未和前端代码部署的服务器资源在同一台服务器上,此时前端使用的图片资源已经跨域了,若将跨域的图片显示在canvas上,这时canvas已经被污染了,无法再获取图片的base64位编码信息。
网上的解释是:canvas上显示了跨域资源后,由于浏览器的保护机制,使前端无法在canvas上进行像素操作,如getImageData、toDataURL等API。跨域一般通过CORS(Corss Origin Resource Sharing 跨域资源共享)方式解决,大致有以下几种方式:
1、前端解决跨域问题
Image对象设置成允许跨域,如

1
image.crossOrigin = "Anonymous"

若该方法还是不行,则在网关或者在后端返回该资源的地方需要进行CORS设置。
2、后端进行CORS设置
3、前端通过ngnix代理
前端将API接口通过ngnix代理设置成与后端同一个域名的接口,进而就不存在跨域问题了。
4、修改浏览器的保护机制,使其允许前端获取跨域的资源。(治标不治本)