上篇:
上篇我们给地图添加了锐化、模糊等滤镜,这篇来写一个小工具给图片调色。
调色比锐化等滤镜要简单许多,直接拿到像素值修改即可。不需要用到卷积核。。。(*^▽^*)
核心原理就是图像结构,使用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; // Red
data[i + 1] = data[i + 1] + brightness; // Green
data[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>