Sort PImage array by brightness

Here is an additional solution for the same problem.

It loads the three Processing logos 1 2 3, then sorts them by brightness, 3, 1, 2.

The code creates a Comparator – a Java object for comparing two objects and determining which is bigger / first / brighter / more – and then passes the comparator to Arrays.sort(), which uses it to sort a PImage[] array.

import java.util.Arrays;
/**
 * Sort PImage array by brightness
 * 
 * https://discourse.processing.org/t/sort-pimage-array-by-brightness/19423
 */
import java.util.Comparator;

void setup() {
  size(720,240);
  PImage[] imgs = new PImage[3];
  imgs[0] = loadImage("Processing_1_logo.png");
  imgs[1] = loadImage("Processing_2_logo.png");
  imgs[2] = loadImage("Processing_3_logo.png");
  Arrays.sort(imgs, CMP_PIMG_BRIGHT_AVG);
  for(int i=0; i<imgs.length; i++) {
    image(imgs[i],0,0);
    text((int)brightAvg(imgs[i]), 20, 20);
    translate(240,0);
  }
  save("PImageBrightSort--screenshot.png");
}

long brightSum(PImage img) {
  img.loadPixels();
  long bright = 0;
  for(int i=0; i<img.pixels.length; i++) bright+=brightness(img.pixels[i]);
  return bright;
}

double brightAvg(PImage img) {
  long bright = brightSum(img);
  return bright/(double)img.pixels.length;
}

Comparator<PImage> CMP_PIMG_BRIGHT_SUM = new Comparator<PImage>() {
  @ Override public final int compare(final PImage a, final PImage b) {
    long asum = brightSum(a);
    long bsum = brightSum(b);
    if(asum>bsum) return 1;
    if(bsum>asum) return -1;
    return 0;
  }
};

Comparator<PImage> CMP_PIMG_BRIGHT_AVG = new Comparator<PImage>() {
  @ Override public final int compare(final PImage a, final PImage b) {
    double aAvg = brightAvg(a);
    double bAvg = brightAvg(b);
    if(aAvg>bAvg) return 1;
    if(bAvg>aAvg) return -1;
    return 0;
  }
};

There are some subtleties to sorting PImage by brightness –

  1. what if the images are two different sizes?
  2. what if either image has transparent pixels?

This example provides two Comparators – a sum (raw pixels) and an average – and uses the average.

See previous discussion with PVector: Sort PVector array by distance

2 Likes