【第4章 图像与视频】4.6 结合剪辑区域来绘制图像

文章目录


前言

本节将综合运用图像处理、离屏 canvas 以及剪辑区域等技术实现墨镜效果。


示例

主线程代码:

html 复制代码
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>4-18-综合运用图像处理、离屏canvas以及剪辑区域等技术的墨镜效果演示</title>
		<style>
			#canvas {
				background: rgba(0, 0, 0, 0.4);
			}
		</style>
	</head>
	<body>
		<div id="controls">墨镜滤镜<input type="checkbox" id="sunglassCheckbox" /></div>
		<canvas id="canvas" width="800" height="600"> canvas not supports </canvas>

		<script>
			const canvas = document.getElementById('canvas'),
				context = canvas.getContext('2d'),
				sunglassCheckbox = document.getElementById('sunglassCheckbox'),
				offscreenCanvas = document.createElement('canvas'),
				offscreenContext = offscreenCanvas.getContext('2d'),
				sunglassFilter = new Worker('./sunglassFilter.js'),
				LENS_RADIUS = canvas.width / 5

			const image = new Image()

			offscreenCanvas.width = canvas.width
			offscreenCanvas.height = canvas.height

			// Functions......
			function drawOriginalImage() {
				context.drawImage(image, 0, 0, canvas.width, canvas.height)
			}

			// 绘制镜片
			function drawLenses(leftLensLocation, rightLensLocation) {
				context.save()

				context.beginPath()
				context.arc(leftLensLocation.x, leftLensLocation.y, LENS_RADIUS, 0, Math.PI * 2, false)
				context.stroke()

				moveTo(rightLensLocation.x, rightLensLocation.y)
				context.arc(rightLensLocation.x, rightLensLocation.y, LENS_RADIUS, 0, Math.PI * 2, false)
				context.stroke()

				context.clip()
				context.drawImage(offscreenCanvas, 0, 0, canvas.width, canvas.height)

				context.restore()
			}

			// 绘制镜线
			function drawWire(center) {
				context.beginPath()
				context.moveTo(center.x - LENS_RADIUS / 4, center.y - LENS_RADIUS / 2)
				context.quadraticCurveTo(
					center.x,
					center.y - LENS_RADIUS + 20,
					center.x + LENS_RADIUS / 4,
					center.y - LENS_RADIUS / 2
				)
				context.stroke()
			}

			function putSunglassesOn() {
				const imagedata = context.getImageData(0, 0, canvas.width, canvas.height),
					center = {
						x: canvas.width / 2,
						y: canvas.height / 2,
					},
					leftLensLocation = {
						x: center.x - LENS_RADIUS - 10,
						y: center.y,
					},
					rightLensLocation = {
						x: center.x + LENS_RADIUS + 10,
						y: center.y,
					}

				sunglassFilter.postMessage(imagedata)

				sunglassFilter.onmessage = (e) => {
					offscreenContext.putImageData(e.data, 0, 0)
					drawLenses(leftLensLocation, rightLensLocation)
					drawWire(center)
				}
			}

			// Event handlers......
			sunglassCheckbox.onchange = () => {
				if (sunglassCheckbox.checked) {
					putSunglassesOn()
				} else {
					drawOriginalImage()
				}
			}

			// Initialization......
			image.src = './waterfall.png'
			image.onload = () => {
				drawOriginalImage()
			}
		</script>
	</body>
</html>

Worker线程代码:

javascript 复制代码
self.onmessage = function (e) {
	const imagedata = e.data,
		data = imagedata.data,
		width = imagedata.width,
		length = data.length

	for (let i = 0; i < length; ++i) {
		if ((i + 1) % 4 != 0) {
			if ((i + 4) % (width * 4) == 0) {
				data[i] = data[i - 4]
				data[i + 1] = data[i - 3]
				data[i + 2] = data[i - 2]
				data[i + 3] = data[i - 1]
			} else {
				data[i] = 2 * data[i] - data[i + 4] - 0.5 * data[i + 4]
			}
		}
	}

	self.postMessage(imagedata)
}

相关推荐
鱼钓猫4 小时前
H5 电子签名组件
vue.js·canvas
小鱼儿亮亮1 天前
canvas中常见问题的解决方法及分析,踩坑填坑经历
前端·canvas
普兰店拉马努金2 天前
【Canvas与图标】古铜色“HTML”图标
html·canvas·图标
wayhome在哪12 天前
Cropper.js 轻松拿捏前端裁剪🤞
javascript·canvas·设计
PineappleCoder16 天前
SVG 适合静态图,Canvas 适合大数据?图表库的场景选择
前端·面试·canvas
德育处主任17 天前
p5.js 用 cylinder() 绘制 3D 圆柱体
前端·数据可视化·canvas
蛋蛋_dandan19 天前
Fabric.js从0到1实现图片框选功能
canvas
wayhome在哪21 天前
用 fabric.js 搞定电子签名拖拽合成图片
javascript·产品·canvas
德育处主任21 天前
p5.js 掌握圆锥体 cone
前端·数据可视化·canvas
德育处主任22 天前
p5.js 3D 形状 "预制工厂"——buildGeometry ()
前端·javascript·canvas