简体   繁体   English

处理 - 放大单击的区域,然后再次单击以缩小

[英]Processing - Zoom on clicked area then click again to zoom back out

I have a picture then used a flashlight type of light to only show where the mouse is hovering over.我有一张图片,然后使用手电筒类型的光来仅显示鼠标悬停的位置。 That part of the code works, but now I want to use if/else statements to zoom in on the selected area and then click again to zoom back out.该部分代码有效,但现在我想使用if/else语句放大所选区域,然后再次单击以缩小。 Any other way to zoom in on specific area then back out of that area also helps.任何其他放大特定区域然后退出该区域的方法也有帮助。 Really any help will be appreciated!真的任何帮助将不胜感激!

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();
}

Here is my interpretation of what you are talking about.这是我对你所谈论的内容的解释。 We store a isClicked boolean to store the state of whether we should zoom in or not.我们存储一个isClicked布尔值来存储我们是否应该放大的状态。 When we are going to draw the image, we translate() to the mouse, then we scale() , then we translate() back the same amount that we moved before, but in the opposite direction.当我们要绘制图像时,我们translate()到鼠标,然后我们scale() ,然后我们translate()回到我们之前移动的相同量,但方向相反。 What this does is it does the scale transform around the mouse position.它的作用是围绕鼠标位置进行缩放变换。

One thing that I couldn't find a way around way your way of updating the pixels directly from the image and the flashlight effect.有一件事,我无法找到直接从图像和手电筒效果更新像素的方法。 What the program is doing instead is using your method to make a mask image and applying that to a PGraphics object.程序正在做的是使用您的方法制作蒙版图像并将其应用于PGraphics对象。 Another thing that I noticed is that when just rendering straight to the screen, there is considerable lag from the scaling.我注意到的另一件事是,当直接渲染到屏幕时,缩放会有相当大的滞后。 Instead, I have moved the drawing to a PGraphics object.相反,我已将绘图移至PGraphics对象。 This improves the performance.这提高了性能。

In the end, to render, the program is drawing everything on the PGraphics object, then applying the mask to that object to get the flashlight effect.最后,为了渲染,程序在PGraphics对象上绘制所有内容,然后将遮罩应用于该对象以获得手电筒效果。

Here is the code that I have:这是我拥有的代码:

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;
}

In my comment, I asked about having the screen move to the mouse, which is what this is doing.在我的评论中,我询问了让屏幕移动到鼠标的问题,这就是这样做的。 If you want to "freeze" the screen in one position, what you can do is store a lastMouseClickPosition PVector or simply just ints.如果您想将屏幕“冻结”在一个位置,您可以做的是存储一个lastMouseClickPosition PVector 或只是简单的整数。 Then, when translating, translate to the position instead of the PVector.然后,在平移时,平移到位置而不是 PVector。

Here's the code that would change:这是将要更改的代码:

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM