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

相关推荐
ncj3934379061 天前
【第4章 图像与视频】4.5 操作图像的像素
canvas
ncj3934379063 天前
【第1章 基础知识】1.8 在 Canvas 中使用 HTML 元素
canvas
七月shi人8 天前
Canvas设计图片编辑器全讲解(一)Canvas基础(万字图文讲解)
前端·javascript·canvas
wuhen_n9 天前
Canvas进阶篇:鼠标交互动画
javascript·html5·canvas·canvas动画·canvas拖拽
追求者201610 天前
实现图片自动压缩算法,canvas压缩图片方法
前端·javascript·canvas
prog_610323 天前
【笔记】当个自由的书籍收集者从canvas得到png转pdf
pdf·canvas·js·png
wuhen_n1 个月前
Canvas特效实例:黑客帝国-字母矩阵(字母雨)
前端·javascript·矩阵·html5·canvas·canva可画
_lucas1 个月前
用canvas做个场景编辑器
前端·javascript·canvas