Hey
I'm having an issue with masking a transparent image.
My mask is dynamically created with a PGraphics object, and basically has a dynamically sized pie-slice area of white in it.
My original image is basically just a transparent image with a ring on it.
What I want is for only the ring to appear when I use the mask.
But instead the transparent colors in my original image turn white/black because of the mask function.
Wouldn't it be more logical for the mask to take the transparent image's alpha into account when applying the mask?
I've written a small piece of code that illustrates the problem.
Everything transparent in my green ring image turns black.
Why?
I'd also be happy for any tips on improvements on my mask function. Maybe with bitshifting?
Code:
// This shows what I'm talking about..
// Only the green ring should appear when masking
boolean buggy = true; // switch to false to see the working version
PGraphics gimg;
PImage img;
void setup()
{
size(150,150);
// Drawing a green ring on a transparent PGraphics.
gimg = createGraphics(width,height, JAVA2D);
gimg.beginDraw();
gimg.smooth();
gimg.stroke(0,255,0);
gimg.strokeWeight(4);
gimg.noFill();
gimg.ellipse(width/2,height/2,width*0.9,height*0.9);
gimg.endDraw();
}
void draw()
{
background(255,0,0);
// Converting that to PImage (so I can use .mask without renderer problems).
img = createImage(width,height, ARGB);
img.copy(gimg,0,0,width,height,0,0,width,height);
// Drawing the mask to a PGraphics.
PGraphics pgMask = createGraphics(img.width,img.height, JAVA2D);
pgMask.beginDraw();
pgMask.smooth();
pgMask.noStroke();
pgMask.fill(255);
pgMask.arc(pgMask.width/2,pgMask.height/2,pgMask.width*2,pgMask.height*2, 0, ((float)frameCount/40)%TWO_PI);
pgMask.endDraw();
// Applying the mask
if(buggy){
img.mask(pgMask); // DOES NOT WORK LIKE I WANT TO
}else{
mask(img,pgMask); // WORKS LIKE I WANT TOO
}
image(img,0,0);
if(mousePressed){ // show ring image
image(pgMask,0,0);
}
}
/* from Processing 1.0.9 - PGrahics.java - with modifications */
public void mask(PImage img, PImage mask)
{
img.loadPixels();
// don't execute if mask image is different size
if (mask.pixels.length != img.pixels.length) {
throw new RuntimeException("The PImage used with mask() must be " +
"the same size as the applet.");
}
int c = GUI.color(255);
for (int i = 0; i < img.pixels.length; i++) {
if(mask.pixels[i] != c)
{
// clear the alpha byte
img.pixels[i] &= 0x00ffffff;
}
}
img.format = 2; // ARGB
img.updatePixels();
}
boolean matchColors(int c, int c2)
{
return (red(c) == red(c2) && green(c) == green(c2) && blue(c) == blue(c2));
}