Loading on PImage on top of another

Hello

I’m trying to load several images into a single PImage object but I’m having issues with transparancy. Rendering the images directly onto the screen goes flawlessly but I’m trying to “buffer” all the layers that make up a single image into a single PImage object.

I’m trying to do this with PImage.pixels[] but it doesn’t seem to work. Here’s what I have;

void draw() {
  //background(0);
  PImage base = createImage(70, 80, ARGB);
  drawOver(base, images.get("right_arm1.png"), 40, 7);
  drawOver(base, images.get("right_sleeve_wave1.png"), 40, 26);
  image(base, 0, 0);
  /*image(images.get("right_arm1.png"), 40, 7);
  image(images.get("right_sleeve_wave1.png"), 40, 26);*/
  
}

void drawOver(PImage base, PImage toAdd, int x, int y) {
  int index = (base.width) * y + x;
  for (int i = 0; i < toAdd.height; i++) {
    for (int j = 0; j < toAdd.width; j++) {
      base.pixels[index] = toAdd.pixels[i*toAdd.width + j];
      index++;
    }
    index += base.width-toAdd.width;
  }
}

PImage convert(PImage base) {
  PImage newImg = createImage(base.width, base.height, ARGB);
  for (int i = 0; i < base.pixels.length; i++) {
    if (base.pixels[i] == color(255, 255, 255)) {
      newImg.pixels[i] = color(255, 255, 255, 0);
    } else {
      newImg.pixels[i] = base.pixels[i];
    }
  }
  return newImg;
}

convert() is used straight after loading the images to remove whitespace by making them transparant. drawOver() is my way of “buffering” one image into another and the core of it works, just that the result image doesn’t allow for transparancy.

not tested if that solves your problem,
but try a structure like

PImage base;

void setup() {
  size(500,500); 
  base = createImage(70, 80, ARGB);
  drawOver(base, images.get("right_arm1.png"), 40, 7);
  drawOver(base, images.get("right_sleeve_wave1.png"), 40, 26);
}

void draw() {
  background(0);
  image(base, 0, 0);
}

as transparency goes to black ( better full color )
if you draw same picture over, again and again 60 times per sec.

Tried this, same issue

Can you share right_arm1.png and right_sleeve_wave1.png for testing?

Hope this isn’t too much of a distraction but why not use blend()?
blended

PImage one,two,three;

void setup(){
  size(200,200);
  one=loadImage("/data/img1.png");
  two=loadImage("/data/img2.png");
  //copy of one
  three=loadImage("/data/img1.png");
  //combine part of two with part of the copy of one
  three.blend(two,20,20,30,30,20,20,30,30,NORMAL);
}

void draw(){
  background(0);
  image(one,30,30);
  image(two,100,30);
  //blended image
  image(three,120,110);
}

if you wrap blend() in a function that takes in and returns a PImage you might be able to simplify the function as well.

I should add that there’s a ton of different Blend “Modes”, maybe one will match the exact use case that you want.

They’re a bit confusing, so the best thing to do to try it is to make a bunch of demos and figure out which mode does what.
BLEND, ADD, SUBTRACT, LIGHTEST, DARKEST, DIFFERENCE, EXCLUSION, MULTIPLY, SCREEN, OVERLAY, HARD_LIGHT, SOFT_LIGHT, DODGE, BURN

The documentation for blend describes what each one does. OVERLAY or NORMAL might do what you want and keep transparency.

1 Like

Thanks for the responses everyone!

I’ve fixed the issue by using PGraphics as a buffer on which I drew the images before drawing the PGraphics onto the screen and that fixed the transparency issue.

I had looked into blend() but refrained from using it because of the modes.

1 Like