Crop multiple images to any (quad) shape and place them side by side filling the canvas (comic strip)

Hi @Twooze,

Welcome to the forum! :wink:

This is an interesting problem, I tried to solve it in my free time so thanks for that!

As pointed by @Chrisir, you can achieve that by using the mask() function. It uses grayscale data to mask parts of an image: dark for deleting parts and white for keeping them.

Let’s suppose you have an image and you want to crop it with a quad that has a shear angle of 20 degrees:

You can compute the coordinates of the quad to draw and display that on an empty image in white (to mask the rest):

PImage maskImageWithQuad(PImage img, float shearAngle) {
  // Use the same dimensions for mask()
  PGraphics quadMask = createGraphics(img.width, img.height); 
  
  // Compute the distance for the coordinates
  float shearDist = img.height * tan(radians(shearAngle));
  
  // Draw the quad on an off-screen canvas
  quadMask.beginDraw();
  quadMask.fill(255);
  quadMask.quad(0, 0, shearDist, img.height, img.width, img.height, img.width - shearDist, 0);
  quadMask.endDraw();
  
  // Make a copy of the image and apply the mask
  PImage maskedImage = img.copy();
  maskedImage.mask(quadMask);
  
  return maskedImage;
}

And use it like this:

PImage img = loadImage(...);
PImage masked = maskImageWithQuad(img, 20); // in degrees

You need to handle the edge cases where the first and last image are not masked with the same quad (the x coordinates of some points are not offset).

Now this is nice but you also need to randomly create the layout with rows of same height but different number of images / orientation. For each row, choose a random orientation (left, vertical or right) and a random number of images to display.

I won’t give the full code now but here are the different collage I am getting (using images from Lorem Picsum):

Tell me if you have more questions!

4 Likes