如何在Processing中实现图形区域内的像素颜色反转
好问题!你提到的DIFFERENCE混合模式其实在彩色模式下也能实现局部反转——只是需要搭配白色作为绘制颜色,而不是随便用其他颜色。另外还有几种基于Processing内置功能的高效方案,我给你逐一拆解:
方案1:
blendMode(DIFFERENCE) + 白色绘制(最优先,性能最高) 这是最高效的实现方式,完全依赖Processing的硬件加速混合模式,没有额外的像素计算开销。
原理:DIFFERENCE混合模式的逻辑是对RGB三个通道分别计算abs(目标像素值 - 源像素值)。当你用**纯白色(255,255,255)**绘制图形时,每个通道的计算结果就是abs(原像素值 - 255),这正好是该通道的反转值,完美实现局部彩色反转。
代码示例:
void setup() { size(600, 400); background(100, 150, 200); // 彩色背景 } void draw() { // 先绘制底层内容(这里用随机椭圆模拟) fill(random(255), random(255), random(255)); noStroke(); ellipse(random(width), random(height), 30, 30); // 开启DIFFERENCE混合模式,绘制白色图形实现局部反转 blendMode(DIFFERENCE); fill(255); // 必须用白色! noStroke(); ellipse(mouseX, mouseY, 100, 100); // 鼠标跟随的反转椭圆 // 恢复默认混合模式,避免影响后续绘制 blendMode(BLEND); }
方案2:
PGraphics离屏缓冲区(精准控制反转区域) 如果需要更精细的区域控制(比如先定义复杂的反转形状,再批量处理),可以用Processing的PGraphics做离屏渲染,这也是内置功能:
步骤:
- 先把所有底层内容绘制到主画布
- 创建一个
PGraphics对象,绘制你需要反转的区域(白色填充,其余透明) - 遍历像素,对遮罩覆盖的区域进行反转
代码示例:
PGraphics invertMask; void setup() { size(600, 400); invertMask = createGraphics(width, height); background(100, 150, 200); } void draw() { // 绘制底层动态内容 fill(random(255), random(255), random(255)); ellipse(random(width), random(height), 30, 30); // 更新反转遮罩:绘制鼠标位置的圆形区域 invertMask.beginDraw(); invertMask.background(0, 0); // 透明背景 invertMask.fill(255); invertMask.noStroke(); invertMask.ellipse(mouseX, mouseY, 100, 100); invertMask.endDraw(); // 提取并反转遮罩内的像素 loadPixels(); invertMask.loadPixels(); for (int i = 0; i < pixels.length; i++) { // 仅处理遮罩中白色的区域(即需要反转的部分) if (invertMask.pixels[i] == color(255)) { color original = pixels[i]; pixels[i] = color(255 - red(original), 255 - green(original), 255 - blue(original)); } } updatePixels(); }
方案3:
mask()方法(适合静态反转区域) 如果你的反转区域是固定的(比如一个预定义的形状或图片遮罩),可以用mask()方法配合像素反转,适合静态场景:
原理:先绘制底层内容,再创建一个反转后的版本,用遮罩只显示需要反转的区域。不过动态场景下性能不如前两个方案。
内容的提问来源于stack exchange,提问作者rndmqstns




