Обработка - увеличьте область нажатия, затем нажмите еще раз, чтобы уменьшить масштаб - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть картинка, затем я использовал тип фонарика, чтобы показать, где находится мышь. Эта часть кода работает, но теперь я хочу использовать операторы if / else , чтобы увеличить выбранную область, а затем снова щелкнуть, чтобы уменьшить масштаб. Любой другой способ увеличить определенную область c и затем вернуться из этой области также помогает. Действительно любая помощь будет оценена!

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

1 Ответ

0 голосов
/ 13 февраля 2020

Вот моя интерпретация того, о чем вы говорите. Мы храним логическое значение 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);
}
...