How to create mask for transparency between 2 pictures

edited April 2014 in Questions about Code

Hi Folks,

I have a project that I have a image in the foreground and I would like to create a tranparency mask to show the picture in the background. I would like to do like this project.

This is the code I have so far but it just load 1 image. How can I do it?

// Learning Processing
// Daniel Shiffman
// http://www.learningprocessing.com

// Example 15-9: Adjusting image brightness based on pixel location (Flashlight effect)

PImage img;

void setup() {
  size(200,200);
  img = loadImage( "sunflower.jpg" );
}

void draw() {
  loadPixels();

  // We must also call loadPixels() on the PImage since we are going to read its pixels.  img.loadPixels(); 
  for (int x = 0; x < img.width; x++ ) {
    for (int y = 0; y < img.height; y++ ) {

      // Calculate the 1D pixel location
      int loc = x + y*img.width;

      // Get the R,G,B values from image
      float r = red (img.pixels[loc]);
      float g = green (img.pixels[loc]);
      float b = blue (img.pixels[loc]);

      // Calculate an amount to change brightness
      // based on proximity to the mouse
      float distance = dist(x,y,mouseX,mouseY);

      // The closer the pixel is to the mouse, the lower the value of "distance" 
      // We want closer pixels to be brighter, however, so we invert the value with the formula: adjustBrightness = (50-distance)/50 
      // Pixels with a distance of 50 (or greater) have a brightness of 0.0 (or negative which is equivalent to 0 here)
      // Pixels with a distance of 0 have a brightness of 1.0.
      float adjustBrightness = (50-distance)/50;
      r *= adjustBrightness;
      g *= adjustBrightness;
      b *= adjustBrightness;

      // Constrain RGB to between 0-255
      r = constrain(r,0,255);
      g = constrain(g,0,255);
      b = constrain(b,0,255);

      // Make a new color and set pixel in the window
      color c = color(r,g,b);
      pixels[loc] = c;
    }
  }

  updatePixels();  
}

Answers

  • edited April 2014

    Perhaps that's similar to the request in this recent thread?
    http://forum.processing.org/two/discussion/4696/erase-effect

  • It is similar but what I would like to accomplish is having 2 pictures 1 in the foreground and 1 in the background, the mask would make the transparency.

    The link have a black color in the foreground and use a random color as mask.

    Please how can I do it?

  • The link have a black color in the foreground and use a random color as mask.

    The black foreground is the mask! The randomly-colored background is a temporary repĺacement for the video-feed for the guy!

  • Well part of it I got it.

    Know I would like to apply the xray mask just in the part that I am pressin the mouse

    PImage a, b;
    float offset;
    int xPos = 0;
    
    void setup()
    {
      size(800,800);
      a = loadImage("window1.jpg");
      b = loadImage("window2.jpg");
    }
    
    void draw()
    {
      xPos++;
      if (xPos == width) {
        xPos = 0;
      }
      image(a, 0, 0);
    
      float offsetTarget = map(xPos, 0, width, -b.width/2 - width/2, 0);
      offset += (offsetTarget-offset)*0.2;
      tint(255, 153);
      image(b, offset, 0);
    }
    

    01-05-2014 19-35-02

    how do I integrate both codes?

    tks

  • edited May 2014

    My code directly manipulates a PImage's pixels[] in a chosen squared area of it.
    While yours use tint(), which affects the whole canvas.

    Another problem is that I still can't figure out this:

    I would like to apply the xRay mask just in the part that I am pressing the mouse.

    Apply where, in the fore or back ground image? :-??

  • The xray is the foreground, the mask is tranparent and the foreground is the colored picture ( on the movie below the red car).how do I manipulates a PImage's pixels[] in a chosen squared area ( sorry I am a beginner user yet)

  • edited May 2014

    The xray is the foreground,...

    Excuse me, but you're code sample doesn't have any variable called that! :-w
    Perhaps that is the name you call the mask effect itself?

    ... the foreground is the colored picture (on the movie below the red car).

    It seems like it's just 2 images. Foreground is the car's exterior and the background is some kinda yellow framework of its interior!

    It doesn't seem much diff. from the example I've provided. Only diff. is that the foreground there is 100% black.
    However, that can be replaced by some other foreground PImage of your choice!

    The trick is to manipulate its alpha channel only. At the regions where the alpha is low, we're able to see the background PImage!

  • Considering the code of the exemple you provided, instead of

          // fill bg w/ #000000, which is 100% opaque black:
          java.util.Arrays.fill(bgMask.pixels, #000000);
        }
    
        void draw() {
          // Replace background() w/ your video feed:
          background((color) random(#000000));
    
          // bgMask is the overlay mask:
          image(bgMask, 0, 0);
        }
    

    where above shoul I replace Pimage for the foreground picture and the background ? and how do I do it?

    (void setup() {
      img = loadImage("laDefense.jpg");
    }
    

    Once again I am a beginner, just iniciated with processing 5 days ago. (If is not too much could you rewrite the snippet above (name of the picture is window1.jpeg and window2.jpg)

    Thanks alot

  • edited May 2014

    That's right! Replacing my tar black image is by loading yours w/ loadImage() instead! ;)
    In order to help your case here, I've modified pixelsRect() as alphaRect().
    Now, rather than pass a whole color value as the 2nd parameter,
    we gotta pass an alpha value ranging from 0 to 255.
    So the RGB from the ARGB is kept intact. Only the A part is set! :-j

    /**
     * Pixels-Based Alpha Rect (v1.1)
     * by GoToLoop (2014/Apr)
     *
     * forum.processing.org/two/discussion/4696/erase-effect
     *
     * forum.processing.org/two/discussion/4825/
     * how-to-create-mask-for-transparency-between-2-pictures
     */
    
    static final int DIAM = 0100, FPS = 10;
    PImage bgMask;
    
    void setup() {
      size(800, 600, JAVA2D);
      frameRate(FPS);
      smooth(4);
      imageMode(CORNER);
    
      bgMask = createImage(width, height, ALPHA);
    
      // fill up bg w/ #000000, which is 100% opaque black:
      java.util.Arrays.fill(bgMask.pixels, #000000);
    }
    
    void draw() {
      // Replace background() w/ your video feed:
      background((color) random(#000000));
    
      // bgMask is the foreground overlay mask:
      image(bgMask, 0, 0);
    }
    
    void mousePressed() {
      // Alpha 0 is 100% transparent.
      // Alpha 0xFF 100% opaque:
      alphaRect(bgMask, mouseButton == LEFT? 0 : 0xFF, DIAM);
    }
    
    void alphaRect(PImage img, color a, int dim) {
      dim >>= 1; // diameter to radius.
      a <<= 030; // move alpha channel to its right octet.
    
      final color[] p = img.pixels;
      final int w = img.width, h = img.height;
    
      final int minX = max(mouseX - dim, 0);
      final int maxX = min(mouseX + dim, w);
    
      final int minY = max(mouseY - dim, 0);
      final int maxY = min(mouseY + dim, h);
    
      for (int row = minY; row != maxY;)
        for (int col = minX, rw = w*row++; col != maxX;) {
          final int idx = rw + col++;
          p[idx] = p[idx] & 0xFFFFFF | a;
        }
    
      img.updatePixels();
    }
    
  • edited May 2014

    It is working!!You are the man!!Thanks ALOT.

    Can I ask you one more question?

    Now instead of filling the foreground with black, can I load 1 image in the foreground also?

    So we would have 1 image in the background and 1 image in the background and when we press the mouse we would reveal the blackground?.

    I tried to change the image(

      // bgMask is the foreground overlay mask:
      image(bgMask, 0, 0);
    

    to

      img2 = loadImage("laDefense.jpg");
      image(img2, 0, 0);
    

    Wasnt it suppose to work?

    Best regards

  • edited May 2014

    I've already said that you gotta replace the PImage I've instantiated w/ createImage() and filled up w/ java.util.Arrays.fill()
    with your own loadImage("")! That is, replace lines #12, #20 & #23 w/ your own resource as foreground mask!

    The way my example is set, is to allow testing w/o needing an external file!

    Another thing: avoid loading resources within draw(). That's why setup() exists for!

  • edited May 2014

    Thanks Man. It is working perfectly.

    Now I would like when user click in a determin area to start a video as backgound

    First a determin a area int x = 600; int y = 200; int w = 600; int h = 250;

    Then I created a if condition

             {
              if (mouseX > x && mouseX < x + w && mouseY > y && mouseY < y + h) {
                myMovie = new Movie(this, "better.mp4");
                myMovie.loop();
                image(myMovie, 0, 0);
              } else {
              print("outiside rect");
              }
            }
    

    Please someone can help me to start this movie ?

    Final code is does meanwhile

        import processing.video.*;
        Movie myMovie; 
        static final int DIAM = 0200, FPS = 10;
        PImage bgMask;
        PImage img;
        PImage img2;
    
        int x = 600;
        int y = 200;
        int w = 600;
        int h = 250;
    
    
    
        void setup() {
          size(1600, 1067, JAVA2D);
          frameRate(FPS);
          smooth(4);
          imageMode(CORNER);
    
    
          bgMask = loadImage("laDefense2.jpg");
    
        }
    
        void draw() {
          // Replace background() w/ your video feed:
          //background((color) #00FFFF);
            img = loadImage("laDefense.jpg");
            image(img, 0, 0);
    
          // bgMask is the foreground overlay mask:
          image(bgMask, 0, 0);
        }
    
        void mouseMoved() {
          // Alpha 0 is 100% transparent.
          // Alpha 0xFF 100% opaque:
          alphaRect(bgMask, mouseButton == LEFT? 0 : 0, DIAM);
        }
    
        void alphaRect(PImage img, color a, int dim) {
          dim >>= 1; // diameter to radius.
          a <<= 030; // move alpha channel to its right octet.
    
    
          final color[] p = img.pixels;
          final int w = img.width, h = img.height;
    
          final int minX = max(mouseX - dim, 0);
          final int maxX = min(mouseX + dim, w);
    
          final int minY = max(mouseY - dim, 0);
          final int maxY = min(mouseY + dim, h);
    
    
    
            If click determin region
             {
              if (mouseX > x && mouseX < x + w && mouseY > y && mouseY < y + h) {
                myMovie = new Movie(this, "better.mp4");
                myMovie.loop();
                image(myMovie, 0, 0);
             } else {
              print("outiside rect");
              }
            }
    
    
    
    
          for (int row = minY; row != maxY;)
            for (int col = minX, rw = w*row++; col != maxX;) {
              final int idx = rw + col++;
              p[idx] = p[idx] & 0xFFFFFF | a;
            }
    
          img.updatePixels();
        }
    
Sign In or Register to comment.