如何在p5.js中提取图片像素颜色作为图形填充色?
解决方案
你当前遇到的问题本质是全局get()方法默认读取当前画布的像素值,画布上后续绘制的圆形会覆盖原有图片像素,因此鼠标移动速度慢时会读取到之前绘制的圆形颜色,出现颜色不变、可选范围偏小的问题。你提到的将图片像素存入数组的思路是可行的,同时也有更简便的实现方式,两种可行方案如下:
方案1:直接调用图片实例的get()方法(修改量最小)
p5.js的Image对象自带独立的get()方法,可以直接读取原始图片的对应位置像素,完全不受画布已绘制内容的影响,修改后代码如下:
let img; // 存储图片加载状态,避免加载完成前调用方法报错 let imgLoaded = false; function setup() { createCanvas(400, 400); loadImage('https://upload.wikimedia.org/wikipedia/commons/e/ef/Hayao_Miyazaki.jpg', loadedImg => { img = loadedImg; // 将图片缩放到和画布尺寸一致,保证坐标匹配 img.resize(width, height); image(img, 0, 0); imgLoaded = true; }); noStroke(); } function draw() { if (!imgLoaded) return; // 从原始图片对象读取像素,不受画布内容干扰 let c = img.get(mouseX, mouseY); fill(c); circle(mouseX, mouseY, 30); }
该方案不需要手动处理像素数组,代码改动量小,适合普通交互场景使用。
方案2:提前存入像素数组(性能更高)
如果需要高频读取像素值,提前把像素存入本地数组的性能会更好,实现方式如下:
let img; let pixelColors = []; let imgLoaded = false; function setup() { createCanvas(400, 400); loadImage('https://upload.wikimedia.org/wikipedia/commons/e/ef/Hayao_Miyazaki.jpg', loadedImg => { img = loadedImg; img.resize(width, height); image(img, 0, 0); // 读取图片所有像素存入二维数组 img.loadPixels(); for (let y = 0; y < img.height; y++) { pixelColors[y] = []; for (let x = 0; x < img.width; x++) { // 计算像素在pixels数组中的索引,每个像素占4位:r、g、b、a let index = (x + y * img.width) * 4; pixelColors[y][x] = [ img.pixels[index], img.pixels[index+1], img.pixels[index+2], img.pixels[index+3] ]; } } imgLoaded = true; }); noStroke(); } function draw() { if (!imgLoaded) return; // 边界校验避免鼠标移出画布时报错 let x = constrain(mouseX, 0, width-1); let y = constrain(mouseY, 0, height-1); let c = pixelColors[y][x]; fill(c); circle(mouseX, mouseY, 30); }
该方案直接从内存数组读取数值,读取效率更高,适合需要大量像素计算的复杂交互场景。
内容的提问来源于stack exchange,提问作者user16502467
相关产品推荐
相关产品推荐

