上篇:
上篇我们给地图添加了锐化、模糊等滤镜,这篇来写一个小工具给图片调色。
调色比锐化等滤镜要简单许多,直接拿到像素值修改即可。不需要用到卷积核。。。(*^▽^*)
核心原理就是图像结构,使用context.getImageData获取图像像素结构。
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
图像数据的存储结构,每个像素占用 4 个连续的数组元素,分别表示该像素的红、绿、蓝和透明度(Alpha)值。具体结构如下:
[ R, G, B, A, R, G, B, A, R, G, B, A, ... ]
假设我们有一个 2x2 像素的图像,其像素颜色如下:
- (0, 0): 红色 (255, 0, 0, 255)
- (1, 0): 绿色 (0, 255, 0, 255)
- (0, 1): 蓝色 (0, 0, 255, 255)
- (1, 1): 白色 (255, 255, 255, 255)
每个像素占用 4 个连续的数组元素,分别表示该像素的红、绿、蓝和透明度(Alpha)值。具体结构如下:
[ 255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255 ]
调整颜色只需要遍历图像数组,改对应的值就好。比如修改亮度,就是把数组中所有的红绿蓝颜色的值都加上滑块的值,数值越接近255越白,就显得图片越亮。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>简单图片调色</title><style>#canvas {border: 1px solid black;}</style>
</head><body><canvas id="canvas" width="300" height="300"></canvas><br><label for="brightness">亮度:</label><input type="range" id="brightness" min="-100" max="100" value="0"><br><label for="redInput">红:</label><input type="range" id="redInput" min="-100" max="100" value="0"><br><label for="redInput">绿:</label><input type="range" id="greenInput" min="-100" max="100" value="0"><br><label for="redInput">蓝:</label><input type="range" id="blueInput" min="-100" max="100" value="0"><script>// 获取 Canvas 和上下文const canvas = document.getElementById('canvas');const context = canvas.getContext('2d');// 加载图像const img = new Image();img.crossOrigin = 'anonymous'; // 允许跨域加载图像img.src = 'https://t7.baidu.com/it/u=2604797219,1573897854&fm=193&f=GIF'; // 替换为你的图像路径img.onload = function () {context.drawImage(img, 0, 0, canvas.width, canvas.height);};// 调整亮度函数function adjustBrightness(context, brightness) {const imageData = context.getImageData(0, 0, canvas.width, canvas.height);const data = imageData.data;for (let i = 0; i < data.length; i += 4) {data[i] = data[i] + brightness; // Reddata[i + 1] = data[i + 1] + brightness; // Greendata[i + 2] = data[i + 2] + brightness; // Blue}context.putImageData(imageData, 0, 0);}// 调整红通道函数function redChannel(context, brightness) {const imageData = context.getImageData(0, 0, canvas.width, canvas.height);const data = imageData.data;for (let i = 0; i < data.length; i += 4) {data[i] = data[i] + brightness; // Red}context.putImageData(imageData, 0, 0);}// 调整绿通道函数function greenChannel(context, brightness) {const imageData = context.getImageData(0, 0, canvas.width, canvas.height);const data = imageData.data;for (let i = 0; i < data.length; i += 4) {data[i + 1] = data[i + 1] + brightness; // Green}context.putImageData(imageData, 0, 0);}// 调整蓝通道函数function blueChannel(context, brightness) {const imageData = context.getImageData(0, 0, canvas.width, canvas.height);const data = imageData.data;for (let i = 0; i < data.length; i += 4) {data[i + 2] = data[i + 2] + brightness; // Blue}context.putImageData(imageData, 0, 0);}// 监听亮度滑块变化const brightnessInput = document.getElementById('brightness');brightnessInput.addEventListener('input', function () {// 先重绘原始图像context.drawImage(img, 0, 0, canvas.width, canvas.height);// 调整亮度adjustBrightness(context, parseInt(brightnessInput.value, 10));});// 监听红通道滑块变化const redInput = document.getElementById('redInput');redInput.addEventListener('input', function () {// 先重绘原始图像context.drawImage(img, 0, 0, canvas.width, canvas.height);// 调整亮度redChannel(context, parseInt(redInput.value, 10));});// 监听绿通道滑块变化const greenInput = document.getElementById('greenInput');greenInput.addEventListener('input', function () {// 先重绘原始图像context.drawImage(img, 0, 0, canvas.width, canvas.height);// 调整亮度greenChannel(context, parseInt(greenInput.value, 10));});// 监听蓝通道滑块变化const blueInput = document.getElementById('blueInput');blueInput.addEventListener('input', function () {// 先重绘原始图像context.drawImage(img, 0, 0, canvas.width, canvas.height);// 调整亮度blueChannel(context, parseInt(blueInput.value, 10));});</script>
</body></html>