Setting alpha values of pixels and counting total pixels changed

edited April 2014 in How To...

Hey everyone, I'm pretty new to processing and coding in general, so I was going through the tutorial at

http://www.processing.org/tutorials/pixels/

and have hit a problem at this part

http://www.learningprocessing.com/examples/chapter-15/example-15-9/

I want to change the alpha values of the pixels to reveal an image underneath, but instead of having this "flashlight effect", I wanted them to stay at the alpha value set, almost like an erasing effect. Furthermore, I would like to be able to find a value for the total amount of pixels that have been "erased". However, I can't even seem to change the alpha values at all. So far I've used the code from the above example, with an added alpha parameter but it doesnt seem to work, and I don't know why..

Code:

PImage img, city;

void setup() {
  size(450,650);
  city = loadImage( "City.jpg" );
  img = loadImage( "Girl.jpg");
  image(city,0,0,450,650);
}

void draw() {

  loadPixels();

  for (int x = 0; x < img.width; x++ ) {
    for (int y = 0; y < img.height; y++ ) {

      int loc = x + y*img.width;

      float r = red (img.pixels[loc]);
      float g = green (img.pixels[loc]);
      float b = blue (img.pixels[loc]);
      float a = alpha (img.pixels[loc]);

      float distance = dist(x,y,mouseX,mouseY);
      float adjustBrightness = (50-distance)/50;

     // r *= adjustBrightness;
     // g *= adjustBrightness;
     // b *= adjustBrightness;
      a *= adjustBrightness;
      // Constrain RGB to between 0-255
      r = constrain(r,0,255);
      g = constrain(g,0,255);
      b = constrain(b,0,255);
      a = constrain(a,0,255);
     // a = constrain(a,127,255);
      // Make a new color and set pixel in the window
      color c = color(r,g,b,a);
      pixels[loc] = c;

    }
  }

  updatePixels();  
}

I saw that someone else had pretty much the same problem:

http://forum.processing.org/one/topic/working-with-pixels-alpha-values.html

But after reading that I'm still baffled.. I've tried constraining the alpha value above 0 but that doesnt do anything. I've also tried specifying img's pixels directly with img.loadPixels(); , img.pixels[loc] and img.updatePixels() but that doesnt work either..

I'm also open to any other ideas of achieving my desired effect :) Cheers!

Answers

  • The way you're talking about images and alpha makes me unsure if 'alpha' is really what you want to modify. Can you explain how the effect you want to accomplish is different from the example you linked to?

    Are you trying to gradually erase an image off of the top of another? Are you trying to modify the alpha channel of the top image?

    Perhaps this is a good algorithm: continuously, over time, for each pixel near the current mouse position, reduce the existing alpha for the top image value by some small value. Then draw the lower image and lastly, draw the partially cleared upper image.

    If this sounds correct you are going to need to 'loadPixels' for the image whose alpha you want to modify and then after you have changed the pixels, make sure you 'updatePixels'

  • edited April 2014

    Thanks for your reply,

    Yep, I am trying to gradually erase an image off of the top of another, and I was trying to do this by modifying the alpha values of the pixels of the top image. Also, I wanted to do this in a way which would allow me to find a value for the amount of the image erased. My problem being that the alpha values seem unaffected when I run my script :(

    Your algorithm seems like it might work, but I don't know how I'm going to change the existing alpha, since it doesn't work in my example.

  • edited April 2014

    When we use loadPixels() & updatePixels() as functions, we affect the canvas' pixels[].
    If we wanna access a particular PImage's pixels[], we're gonna need its reference:
    Let's say that reference is stored in variable img. So it's img.loadPixels(), img.updatePixels() & img.pixels[]! :-B

  • I've tried that too, but then the PImage ( img in this case) isn't drawn at all.

  • I've found an alternate way of getting a similar effect with the code below, where instead of an above image being erased, the below image is drawn on top:

     for(int y = 0 ; y < size ; y++){
           for(int x = 0; x < size; x++){
    
        int srcX = (int)map(p2d.x+x,0,width+size,0,city.width);
        int srcY = (int)map(p2d.y+y,0,height+size,0,city.height);
        int dstX = (int)map(p2d.x+x,0,width+size,0,girl.width);
        int dstY = (int)map(p2d.y+y,0,height+size,0,girl.height);
        girl.set(dstX, dstY, city.get(srcX,srcY));
    
    }
    }
    

    Where p2d is essentially the mouse position (I'm using a kinect), and size is the size of the "eraser". So now I'm wondering if anyone has an idea about how I can count the total amount of the image, city, that is drawn on top?

    P.S any suggestions about my first problem are still greatly appreciated :D Cheers!

  • Djmadmole, let's talk through this... Before you have the ability to directly modify pixels (either of an image of the background canvas) you first have to call the loadPixels() function for the pixels that you want to modify. Once you have called loadPixels(), all of the pixels will be there for you to read and modify. However, if you want the modified pixels to get saved back into the image you have to call updatePixels(). In other words, until you call updatePixels() all you have is a copy of the pixels that won't show up when you try to draw your image.

    Another note for you is that anything modified with pixels[i] = x and then saved back to the image with updatePixels() will still be in the pixels array the next time draw is called. So, you might be able to imagine what would happen if every frame you added a value to the red value of each pixel in the image...

    Here's a working example of how to load and update an image's alpha value. Post your code if you can figure out how to get the alpha modified!

        PImage customImage;
    
        void setup()
        {
          customImage = loadImage("SomeRandomImage.png");
        }
    
        void draw()
        {
          background(255,0,0);//fill background with red
          customImage.loadPixels(); //fill customImage.pixels array with image data
          float randomAlpha = random(255);
          for(int i = 0; i< customImage.pixels.length; i++)
          {
            float currentPixelRedVal = red(customImage.pixels[i]);
            float currentPixelGreenVal = green(customImage.pixels[i]);
            float currentPixelBlueVal = blue(customImage.pixels[i]);
        //    currentPixelBlueVal = currentPixelBlueVal +1;
        //    if(currentPixelBlueVal > 255)
        //      currentPixelBlueVal = 0;
            //give this pixel the color of
            customImage.pixels[i] = color(currentPixelRedVal, //red
                                          currentPixelGreenVal, //blue
                                          currentPixelBlueVal, //green
                                          randomAlpha); //alpha value (0 = most clear 255 = most opaque) 
          }
          customImage.updatePixels(); //send the modified pixels back into 'customImage'
          image(customImage,0,0,width,height); //draw customImage to fit the screen
        }
    
  • Hey, sorry for the long reply, I have been extremely busy recently and haven't had the time to pursue this project :( Thanks a lot for your code, and I see where I was going wrong before, kind of haha :) This is my code now :

    PImage girl,city;
    
    void setup()
    {
      size(450,650);
      girl = loadImage("Girl.jpg");
      city = loadImage("City.jpg");
    
    }
    
    void draw()
    {
    
      girl.loadPixels(); 
    
      for(int x = 0; x< girl.width; x++)
      {
        for(int y = 0; y< girl.height; y++)
        {
          int i = x + (y * girl.width);
    
        float r = red(girl.pixels[i]);
        float g = green(girl.pixels[i]);
        float b = blue(girl.pixels[i]);
        float aval = alpha(girl.pixels[i]);
        float distance = dist(x,y,mouseX,mouseY);
    
         distance = map(distance,0,650,0,50);
         float mod = distance/2;
    
     float a = mod*aval-100 ;
     a = constrain(a,1,255);
    
        girl.pixels[i] = color(r,g,b,a);
      }
    
    }
      girl.updatePixels(); 
      image(city,0,0,450,650);
      image(girl,0,0,width,height); 
    }
    

    So now how can I find a value for the total amount of pixels that have been changed, or more specifically with their alpha value = 1? Cheers!

Sign In or Register to comment.