Issue with color alpha

edited January 2016 in Questions about Code

Hi,

I was trying to process a PImage to change particular pixels to become transparent but I could not get it to work. For example this would only turn the pixels to black:

img.loadPixels();
for (int x = 0; x < img.width; x++) {
    for (int y = 0; y < img.height; ++y) {
        if (x < y)
            img.set(x, y, color(0, 0));
    }
}
img.updatePixels();

So I tried in a simpler sketch and realized that the 3 rectangles in this sample would have different fill, one transparent, one almost transparent and one black (not expected with alpha to 0):

size(500, 200);
fill(0, 0);
rect(100, 50, 100, 100);
fill(color(0, 1));
rect(200, 50, 100, 100);
fill(color(0, 0));
rect(300, 50, 100, 100);

Can someone explain why does the pixels turn black instead of being transparent?

Thanks!

Answers

  • edited April 2015 Answer ✓
    • That unexpected diff. behavior between fill(0, 0) & fill(color(0, 0)) is b/c any value within the [0 & 255] range is interpreted as opaque grey scale by both fill() & stroke()! @-)
    • color(0, 0) yields exactly 0. So it becomes fill(0).
    • Which ends up interpreted as #000000 (0xff000000), instead of 0x00000000 by fill(). :-B
    • The only way around this is to forcibly specify the alpha parameter as well.
    • Thus fill(color(0, 0), 0) becomes the same as fill(0, 0)! :>
    • Of course, any other range behaves as expected w/o specifying an extra alpha parameter! O:-)
  • edited May 2015 Answer ✓
    /**
     * SetAllColorAlpha (v1.1)
     * by GoToLoop (2015/Apr/13)
     *
     * forum.processing.org/two/discussion/10291/issue-with-color-alpha
     * forum.processing.org/two/discussion/11066/cookie-cut-shape-from-other-shape
     */
    
    static final PImage setAllColorAlpha(PImage img, color c, color a) {
      c  &= ~#000000; // clear alpha channel w/ inverted alpha mask.
      a <<= 030; // shift alpha value to most significant byte (MSB) location.
    
      img.loadPixels();
      color p[] = img.pixels, i = p.length, q;
    
      while (i-- != 0)  if ((q = p[i] & ~#000000) == c)  p[i] = q | a;
    
      img.updatePixels();
      return img;
    }
    
    void setup() {
      size(400, 400, JAVA2D);
      noLoop();
      smooth(4);
      background(#0000FF); // 100% opaque blue canvas.
    
      PGraphics pg = createGraphics(width, height, JAVA2D);
      pg.beginDraw();
    
      pg.background(0); // 100% opaque black image.
      pg.smooth(4);
      pg.ellipseMode(CENTER);
    
      pg.stroke(#FFFF00); // 100% opaque yellow outline.
      pg.strokeWeight(5.0);
      pg.fill(#FF0000); // 100% opaque red circle.
      pg.ellipse(width>>1, height>>1, width>>1, height>>1);
    
      pg.endDraw();
    
      // Set all pg's black pixels to 100% transparent.
      // It won't cover canvas' blue background w/ image() now:
    
      //image(pg, 0, 0); // uncomment this for the result w/ unmodified pg's black.
      image(setAllColorAlpha(pg, 0, 0), 0, 0);
    }
    
  • edited April 2015

    GoToLoop, once more you save the day!

    I had forgot to mention that I did not care preserving the original color so my final version is a little bit simplified but I am sure it will be useful later.

    Playing around with colors and alpha channels always seemed easy before but that case was tricky and proved that I should go back to study!

    Thanks very much!

Sign In or Register to comment.