了解CanvasRenderingContext2D.drawImage()
简介
水印合成,非使用drawImage()
不可。,如图像压缩,对于很多图像相关的处理,或者图像的像素操作等(见最后的相关资源),没有之一。因为Canvas的很多API效果其它web技术也能实现,那就没得选择,CanvasRenderingContext2D.drawImage()
是Canvas与web结合使用最频繁的方法,但是
语法
context;drawImage)image, dx, dy(. context;drawImage)image, dx, dy, dWidth, dHeight(. context;drawImage)image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight(.
参数
各个参数含义和作用如下:
- image Object
- 绘制在Canvas上的元素,可以是各类Canvas图片资源(见
CanvasImageSource
),如<img>
图片,SVG图像,Canvas元素本身等。 - dx Number
- 在Canvas画布上规划一片区域用来放置图片,
dx
就是这片区域的左上角横坐标。 - dy Number
- 在Canvas画布上规划一片区域用来放置图片,
dy
就是这片区域的左上角纵坐标。 - dWidth Number
- 在Canvas画布上规划一片区域用来放置图片,
dWidth
就是这片区域的宽度。 - dHeight Number
- 在Canvas画布上规划一片区域用来放置图片,
dHeight
就是这片区域的高度。 - sx Number
- 表示图片元素绘制在Canvas画布上起始横坐标。
- sy Number
- 表示图片元素绘制在Canvas画布上起始纵坐标。
- sWidth Number
- 表示图片元素从坐标点开始算,多大的宽度内容绘制Canvas画布上。
- sHeight Number
- 表示图片元素从坐标点开始算,多大的高度内容绘制Canvas画布上。
虽然看上去有9大参数,但不用慌,实际上可以就3类参数:
- 第1类就是
image
,同上,没什么好说的; - 第2类就是
dx
,dy
,dWidth
和dHeight
,表示在Canvas画布上划出一片区域用来放置图片,dx
,dy
为canvas元素的左上角坐标,dWidth
,dHeight
指Canvas元素上用在显示图片的区域大小。如果没有指定dx
,dy
,dWidth
和dHeight
这4个参数,则图片会被拉伸或缩放在这片区域内。 - 第3类就是
sx
,sy
,sWidth
和sHeight
,你可以理解为对原始图片的提前剪裁。sx
,sy
表示图片上sx
,sy
这个坐标作为剪裁的左上角,sWidth
和sHeight
尺寸范围是最终剪裁出来的图片尺寸。sx
,sy
,sWidth
和sHeight
这4个参数就可以得到一个剪裁好的新图,然后我们把这个新图放在dx
,dy
,dWidth
和dHeight
这个Canvas画布区域中,就是最终的效果。另外,此处的所有坐标和宽高值都是相对于图片的原始尺寸而言的。
drawImage()
方法有一个非常怪异的地方,大家一定要注意,那就是5参数和9参数用法的参数位置是不一样的,这个和一般的API有所不同。一般API可选参数是放在后面。但是,这里的drawImage()
使用9个参数时候,可选参数sx
,sy
,sWidth
和sHeight
是在前面的。如果不注意这一点,有些表现会让你无法理解。
下图为MDN上原理示意:
案例
下面所有案例使用的图片资源都是下面这一张图,尺寸为500*333。
1. 保持原始图片尺寸和比例
使用context.drawImage(image, dx, dy)
绘制图片,可以保持图片的原始尺寸和比例。
例如:
context.drawImage(image, 0, 0);
结果效果如下:
从实际开发经验来看,当图片的原始尺寸和我们的Canvas画布尺寸一模一样的时候,可以直接只使用image
,dx
,dy
这3个参数。
2. 拉伸图片到指定大小和位置
我们还可以指定Canvas中呈现图片的区域,这个时候,如果我们没有指定图片呈现的位置和尺寸的话,图片会被自动拉伸到这个指定区域内,很可能最终呈现的长宽比和原始图片就不一样。
例如:
context.drawImage(image, 0, 0, 300, 150);
结果效果如下:
可以看到图片虽然看到了全貌,但是被压扁了,不是原始的图片比例,这并不是我们需要的效果,需要进一步调整。
3. 拉伸图片同时保持图片比例
如何填满Canvas画布,同时保持图片的原始比例呢?这个就需要用到sx
,sy
,sWidth
和sHeight
这几个参数,注意,这4个参数是要写在dx
,dy
,dWidth
和dHeight
前面的,和一般的API不一样。
例如:
context.drawImage(image, 0, 42, 500, 250, 0, 0, 300, 150);
结果效果如下:
此案例关键是理解0, 42, 500, 250
这4个坐标是怎么来的。我们最终图片要显示在300*150大小的Canvas画布中,比例是2:1,因此,我们最终设置的用来绘制的图片尺寸比例也是2:1。原始图片宽度是500
,要保持2:1,则高度我们就设置为250
;而原始高度是333
,我们希望显示图片中心区域,因此起始垂直坐标计算下,(333 - 250) / 2
,四舍五入就是42
,因此,就有了对原始图片的剪裁坐标值和尺寸值0, 42, 500, 250
。
其他
规范文档
规范地址 | 规范状态 | 备注 |
---|---|---|
HTML现行标准 这个规范中定义了'CanvasRenderingContext2D.drawImage' |
现行标准 | - |
相关资源
兼容性
基本功能IE9+支持,全兼容。SVG图像绘制,兼容性存疑。
by zhangxinxu 2019-10-18 01:44:04