cut and move circles on the upper layer to see parts of the bottom layer, two images.

edited December 2015 in How To...

Hello there!

I am an artist and a quite new in processing :) I 'd like to achieve the following: I have two different images. I want to put them as layers and then find a way to reveal parts of the bottom image with some circles cut in the upper layer. The circles should be of different size and should be moving freely on the canvas.

It's like having a spotlight searching something into the dark. (This is why I have tried it with the brightness example, but I could not have the upper image since in this specific example is the black canvas.. so brightness doesn't work for me here.)

Any suggestions?

Thank you for your time :)

Answers

  • You are looking for PImage, mask() and PGraphics. Look in the reference, and/or search the forum for mask.

    Here a simple example.

    PImage img1, img2;
    PGraphics pg; 
    
    void setup() {
    
      img1 = loadImage("http:"+"//wordlesstech.com/wp-content/uploads/2012/04/Welcome-to-the-Anthropocene-1.jpg");
      img2 = loadImage("http:"+"//architectsandartisans.com/blog/wp-content/uploads/age-of-man/anthropocene_mm7893_04.jpg");
    
      // hack to wait until image loads to set size
      // no good, specially I think this will break Processing 3.x.x
      // I'm in 2.2.1
      // totally useless for local images.  
      while (img1 == null) {
      }
    
      size (img1.width, img1.height);
    
      // resize image to match other
      img2.resize(width, 0);
    
    
    
      //basic setup of mask layer
      // black is opaque, white transparent
      pg = createGraphics(img2.width, img2.height);
      pg.beginDraw();
      pg.noStroke();
      pg.fill(255);
      pg.background(0);
      pg.endDraw();
    }
    
    void draw() {
    
      // dispaly first image
      image(img1, 0, 0);
    
      //draw a white circle at mouse position IN MASK
      pg.beginDraw();
      pg.ellipse(mouseX, mouseY, 15, 15);
      pg.endDraw();
    
      //get a PImage from PGraphics
      PImage temp = pg.get();
    
      // mask img2 with it
      img2.mask(temp);
    
      //display it
      image(img2, 0, 0);
    }
    
  • _vk thanks for your prompt answer!! I tried your code with my images and it works fine. the thing is that any attempt to write something different instead of mouseX, mouseY does not play anything..maybe the mask and the ellipse drawing produce a kind of conflict? I have a class named ball (from the example bouncing ball) and I put instead of mouseX, mouseY x and y. doesn't work :/

  • _vk_vk
    edited December 2015 Answer ✓

    The idea was to help you understand how it's done... We can't help you much more without your code.

    But it is pretty straightforward.You want to draw white (or gray) stuff in your mask layer. That's it. Try displaying the PGraphics image(pg, 0, 0) without masking anything, and check if you are drawing in it. once you get this working hide it back and use as a mask.

    Or post your code so we can try to go further.

    ;)

  • edited December 2015

    hi again! thank you so much for your tips. It is working now. The only thing is that I am trying to make a function that consists also the PGraphics so that I am able to create more of these "spotlights". I have tried several solutions but nothing is working so I am posting the code. If you have any advice it will be very helpful :) Although I create three balls only one is appearing on the screen. After some experiments it seems it is always the last one I put as extra. Thank you for your time :)

    `PImage img1, img2;
    PGraphics pg; 
    Ball ball1;
    Ball ball2;
    Ball ball3;
    
    void setup() {
    
      img1 = loadImage("3.png");
      img2 = loadImage("4.png");
    
      ball1 = new Ball(10);
      ball2 = new Ball(20);
      ball3= new Ball(40);
    
      while (img1 == null) {
      }
    
      size (640, 380);
    
      // resize image to match other
      img2.resize(width, 0);
    }
    
    void draw() {
      pg = createGraphics(img2.width, img2.height);
      ball1.move();
      ball2.move();
      ball3.move();
    
      ball1.maskIt();
      ball2.maskIt();
      ball3.maskIt();
      //draw a white circle at mouse position IN MASK
       PImage temp = pg.get();
    
      // mask img2 with it
      img2.mask(temp);
    
      //display it
      image(img2, 0, 0);
    }
    
    
    class Ball {
    
      float r;   // radius
      float x,y; // location
      float xspeed,yspeed; // speed
    
      // Constructor
      Ball(float tempR) {
        r = tempR;
        x = random(width);
        y = random(height);
        xspeed = random( - 1,1);
        yspeed = random( - 1,1);
      }
    
      void move() {
        x += xspeed; // Increment x
        y += yspeed; // Increment y
    
        // Check horizontal edges
        if (x > width || x < 0) {
          xspeed *= - 1;
        }
        //Check vertical edges
        if (y > height || y < 0) {
          yspeed *= - 1;
        }
      }
    
      void maskIt()
     {
    
      pg.beginDraw();
      pg.noStroke();
      pg.fill(255);
      pg.background(0);
      pg.endDraw();
      // dispaly first image
      image(img1, 0, 0);
      pg.beginDraw();
      pg.ellipse(x, y, r, r);
      pg.endDraw();
    
      //get a PImage from PGraphics
    
     }
    }
    
  • _vk_vk
    Answer ✓

    Hi, I can't run it right now, but I'd guess the issue is in line83. Each instance of ball is drawing an image covering the previous one. I think the image should be displayed in draw rather than inside the class. I'll run it later anyway to test.

    :)

  • Line 80 is also causing problems: you call background() for each circle thereby erasing the previous circles.

    Also don't call createGraphics() in draw()! This causes a memory leak: it will create a new memory intensive PGraphics object each iteration. You need to move line 26 to setup().

    Maybe you should call pg.beginDraw() and pg.endDraw() once per draw() but it might work fine if you call it more, not sure.

  • @_vk Hi again and happy new year! Although I moved line 83 inside draw() I still cannot display the other circles.. which it's weird... :-/

  • @_vk @colouredmirrorball I just figured it out with your help! I had also to remove line 80 and call background in draw(). Thank you both so much for your help!!! :)

  • _vk_vk
    edited January 2016

    Happy new year :)

Sign In or Register to comment.