【第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)
}

相关推荐
用户2519162427111 小时前
Canvas之图形变换
前端·javascript·canvas
FogLetter2 小时前
用Three.js打造炫酷3D地球:从入门到实现交互式体验
webgl·canvas
寅时码8 小时前
我开源了一款 Canvas “瑞士军刀”,十几种“特效与工具”开箱即用
前端·开源·canvas
德育处主任1 天前
p5.js 用 beginGeometry () 和 endGeometry () 打造自定义 3D 模型
前端·前端框架·canvas
德育处主任3 天前
p5.js 3D模型(model)入门指南
前端·前端框架·canvas
VincentFHR4 天前
Three.js 利用 shader 实现 3D 热力图
前端·three.js·canvas
德育处主任5 天前
p5.js 加载 3D 模型(loadModel)
前端·数据可视化·canvas
用户2519162427115 天前
Canvas之颜色渐变
前端·javascript·canvas
德育处主任6 天前
p5.js 从零开始创建 3D 模型,createModel入门指南
前端·数据可视化·canvas
德育处主任6 天前
p5.js 三角形triangle的用法
前端·数据可视化·canvas