【第4章 图像与视频】4.6 结合剪辑区域来绘制图像
文章目录
- 前言
- 示例
前言
本节将综合运用图像处理、离屏 canvas 以及剪辑区域等技术实现墨镜效果。
示例
主线程代码:
<!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 / 5const image = new Image()offscreenCanvas.width = canvas.widthoffscreenCanvas.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线程代码:
self.onmessage = function (e) {const imagedata = e.data,data = imagedata.data,width = imagedata.width,length = data.lengthfor (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)
}