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 –
- what if the images are two different sizes?
- 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