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

相关推荐
行者-全栈开发12 小时前
华为云码道 CodeArts 实测:让 AI 用纯 TypeScript 写一个确定性回放的塔防小游戏「熵减特勤局」
typescript·小游戏·canvas·ecs·ai 编程·华为云码道·codearts 代码智能体
ji_shuke4 天前
使用 Canvas 和 mix-blend-mode 实现跟随鼠标的反色圆圈
microsoft·计算机外设·canvas
福兮说7 天前
canvas 旋转图片的六个坑:四角被裁、Math.ceil 多出 1px 黑边、JPG 角发黑、翻转方向反了
前端·javascript·图像处理·canvas
格数致用8 天前
01 - Luckysheet电子表格技术原理与架构深度解析
canvas·luckysheet·企业级报表
福兮说8 天前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
miss13 天前
给规则引擎加一个拖拽画布:Vue Flow 单向投影 + 布局语义分离
javascript·vue.js·canvas
JMchen16 天前
自定义View在复杂业务场景中的实战
android·kotlin·canvas
只睡四小时21 天前
Canvas 弹道联机实战:700 行 + 固定时间步长
python·websocket·html5·游戏开发·canvas
JMchen21 天前
属性动画原理与高级动画实现
android·kotlin·canvas
JMchen22 天前
实战案例:实现120fps流畅的渐变进度条
android·kotlin·canvas