我有一张图片,然后使用手电筒类型的灯光仅显示鼠标悬停在的位置。该部分代码有效,但是现在我想使用if / else语句放大所选区域,然后再次单击以缩小。任何其他放大特定区域然后退回到该区域的方法也有帮助。真的,任何帮助将不胜感激!
PImage ispy;
void setup () {
size(1024,768);
ispy = loadImage("ispy2.jpeg");
}
void draw () {
loadPixels();
ispy.loadPixels();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int loc = x+y*width;
float r = red(ispy.pixels[loc]);
float g = green(ispy.pixels[loc]);
float b = blue(ispy.pixels[loc]);
float d = dist(mouseX, mouseY, x, y); //
float factor = map(d, 0, 200, 2, 0);
pixels[loc] = color(r*factor, g*factor, b*factor);
}
}
updatePixels();
}
这是我对您所谈论的内容的解释。我们存储一个isClicked
布尔值以存储是否应放大的状态。当我们要绘制图像时,我们将translate()
移至鼠标,然后我们将scale()
移至鼠标,然后将translate()
移回之前移动的相同量,但方向相反。它的作用是围绕鼠标位置进行比例转换。
我无法找到一种方法,可以直接从图像和手电筒效果中更新像素。程序正在使用您的方法制作蒙版图像,并将其应用于PGraphics
对象。我注意到的另一件事是,当直接在屏幕上渲染时,缩放比例存在相当大的滞后。相反,我将图形移到了PGraphics
对象上。这样可以提高性能。
最后,要渲染,程序将在PGraphics
对象上绘制所有内容,然后将遮罩应用于该对象以获得手电筒效果。
这是我的代码:
PImage ispy, distMask;
boolean isClicked = false;
PGraphics renderer;
void createDistanceMask(PImage distMask){ //Takes image and changes its pixels to "alpha" for the PGraphics renderer
distMask.loadPixels();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int loc = x+(height-y-1)*width;
float d = dist(mouseX, mouseY, x, y); //
int factor = int(map(d, 0, 200, 400, 0)); //Pixel data will be between 0 and 255, must scale down later.
if (factor > 255)
factor = 255;
distMask.pixels[loc] = color(factor,factor,factor);
}
}
distMask.updatePixels();
}
void setup () {
size(1024,768, P2D);
ispy = loadImage("ispy2.jpeg");
distMask = new PImage(width,height);
renderer = createGraphics(width,height,P2D);
mouseX = width/2; //Not necessary, but will have black screen until mouse is moved
mouseY = height/2;
}
void draw () {
background(0);
pushMatrix();
createDistanceMask(distMask);
renderer.beginDraw(); //Starts processing stuff into PGraphics object
renderer.background(0);
if(isClicked){ //This is to get the zoom effect
renderer.translate(mouseX, mouseY);
renderer.scale(2);
renderer.translate(-mouseX, -mouseY);
}
renderer.image(ispy,0,0); //Render Image
renderer.endDraw();
renderer.mask(distMask); //Apply Distance mask for flashlight effect
image(renderer,0,0); //Draw renderer result to screen
popMatrix();
}
void mouseClicked(){
isClicked = !isClicked;
}
在我的评论中,我问过如何将屏幕移动到鼠标上,这是在做什么。如果要“冻结”屏幕到一个位置,您可以执行的操作是存储lastMouseClickPosition
PVector或仅存储整数。然后,在翻译时,翻译到该位置而不是PVector。
这是将要更改的代码:
PVector lastClickPos = new PVector(); //Make the position
if(isClicked){ //When Rendering
renderer.translate(lastClickPos.x, lastClickPos.y);
renderer.scale(scalingFactor);
renderer.translate(-lastClickPos.x, -lastClickPos.y);
}
void mouseClicked(){ //At the bottom
isClicked = !isClicked;
lastClickPos.set(mouseX, mouseY);
}