在p5.js中实现ASCII视频滤镜并给特定字符着色,核心思路是先获取视频的像素数据,根据亮度映射到对应的ASCII字符,再判断字符是否属于目标着色集合,最后分别设置不同的绘制颜色完成渲染。

实现前的准备工作
首先需要确保页面中引入了p5.js库,同时准备一个视频源用于测试。如果是本地开发,需要注意浏览器的视频自动播放策略,建议添加用户交互触发视频播放的逻辑。
核心实现步骤
1. 初始化视频与画布
首先创建视频对象并隐藏原始视频元素,只展示处理后的ASCII画布效果。代码如下:
let video;
let asciiChars = "@%#*+=-:. "; // 亮度从低到高对应的ASCII字符
let targetChars = ["@", "%", "#"]; // 需要着色的特定字符集合
let normalColor, highlightColor;
function setup() {
createCanvas(800, 600);
// 初始化视频,这里使用本地视频或者摄像头都可以
video = createVideo(['test.mp4']);
video.hide(); // 隐藏原始视频元素
video.loop(); // 循环播放
// 定义颜色,普通字符用白色,目标字符用红色
normalColor = color(255, 255, 255);
highlightColor = color(255, 0, 0);
// 添加点击触发视频播放的逻辑,避免浏览器自动播放限制
let playBtn = createButton('点击播放视频');
playBtn.mousePressed(() => {
video.play();
});
}
2. 像素采样与亮度计算
在draw函数中,每一帧都获取视频的像素数据,按照设定的采样间隔提取像素亮度,避免逐像素处理导致性能问题。
function draw() {
background(0); // 黑色背景
video.loadPixels(); // 加载视频像素数据
let cellSize = 12; // 每个ASCII字符的网格大小
textSize(cellSize);
textAlign(CENTER, CENTER);
// 遍历采样网格
for (let y = 0; y < height; y += cellSize) {
for (let x = 0; x < width; x += cellSize) {
// 计算对应视频像素的位置
let videoX = floor(map(x, 0, width, 0, video.width));
let videoY = floor(map(y, 0, height, 0, video.height));
// 获取像素索引,每个像素有RGBA四个通道
let pixelIndex = (videoY * video.width + videoX) * 4;
// 计算亮度,使用加权平均更符合人眼感知
let r = video.pixels[pixelIndex];
let g = video.pixels[pixelIndex + 1];
let b = video.pixels[pixelIndex + 2];
let brightness = (r * 0.299 + g * 0.587 + b * 0.114);
// 将亮度映射到ASCII字符索引
let charIndex = floor(map(brightness, 0, 255, asciiChars.length - 1, 0));
let currentChar = asciiChars[charIndex];
// 判断当前字符是否需要着色
if (targetChars.includes(currentChar)) {
fill(highlightColor);
} else {
fill(normalColor);
}
// 绘制字符
text(currentChar, x + cellSize/2, y + cellSize/2);
}
}
}
3. 自定义着色规则扩展
如果需要更灵活的着色逻辑,比如根据字符亮度区间着色,或者给不同字符设置不同颜色,可以修改判断逻辑。例如给不同目标字符设置不同颜色的实现:
// 定义字符和颜色的映射关系
let charColorMap = {
"@": color(255, 0, 0),
"%": color(0, 255, 0),
"#": color(0, 0, 255)
};
// 修改draw函数中的颜色判断部分
if (charColorMap.hasOwnProperty(currentChar)) {
fill(charColorMap[currentChar]);
} else {
fill(normalColor);
}
参数调整建议
可以通过调整以下参数优化效果:
- cellSize:网格大小,值越小字符越密集,细节越多,性能消耗也越高
- asciiChars:字符序列,可以根据需要调整字符的顺序和数量,改变明暗表现
- targetChars:目标字符集合,可以按需添加或删除需要着色的字符
- 采样间隔:如果性能不足,可以适当增大cellSize,或者降低视频的分辨率
常见问题说明
如果遇到视频无法加载的问题,首先检查视频路径是否正确,本地开发时建议使用相对路径,或者将视频放在同一目录下。如果是摄像头采集,需要添加获取摄像头权限的逻辑,代码如下:
// 使用摄像头作为视频源的实现
function setup() {
createCanvas(800, 600);
video = createCapture(VIDEO);
video.size(800, 600);
video.hide();
// 后续颜色初始化逻辑同上
}
另外需要注意,当cellSize设置过小时,字符可能会重叠,此时可以适当调小textSize,或者增大canvas的尺寸来适配。
p5.jsASCII_视频滤镜字符着色canvas视频处理修改时间:2026-07-07 16:39:27