# Sort PImage array by brightness

**URL:** <https://discourse.processing.org/t/sort-pimage-array-by-brightness/19423>\
**Category:** Coding Questions\
**Created:** [April 5, 2020, 6:17am UTC](https://discourse.processing.org/t/sort-pimage-array-by-brightness/19423 "2020-04-05T06:17:15Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![TimoL](https://avatars.discourse-cdn.com/v4/letter/t/9fc29f/32.png) [@TimoL](https://discourse.processing.org/u/TimoL)\
**Post date:** [April 5, 2020, 6:17am UTC](https://discourse.processing.org/t/sort-pimage-array-by-brightness/19423/1 "2020-04-05T06:17:15Z")

</div>

Hi there,

I have an array of say 10 images and I’m trying to re-order their indexing based on the overall brightness of each image.

Darkest image is 0 & brightest is 10.

I then want to save out each image with its new index:  
image01 to image10.

I feel like I’m really close.  
I can manage to sort the array of brightness values, but I need to apply this sorting to the PImage array.

I’ve been looking at this for far too long today. Hopefully, someone can point me in the right direction.

thanks internet friends!

```auto

PImage [] source; // images to re-order
float [] bScore; //array of brightness "scores" for the images 

void setup () {
  size(20,20);
  source = new PImage[10];
  bScore = new float [10];
  
  for(int i = 0; i < 10; i ++) {
    source[i] = loadImage(sketchPath("data/test_"+i+".jpg") );
    source[i].loadPixels();
    
    bScore[i] = score(source[i]); 
  }
  bScore = sort(bScore);
  printArray(bScore);
}

//function to calculate brightness for each image
float score(PImage source) {
  float avg = 0.0;
  source.loadPixels();
  
  for(int i = 0; i < source.pixels.length; i ++) {
    float b = brightness(source.pixels[i]);    
    avg += b;
  }
    avg /= source.pixels.length;  
    return avg;
  
}

```

the source images are just random b&w squares:

 ![Screenshot 2020-04-05 at 18.16.29](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/5/589eec7ddc10c357d622ff387fab5097ab77c9d0.png)

---

<div class="post-metadata">

**Author:** ![Odermonicon](https://avatars.discourse-cdn.com/v4/letter/o/96bed5/32.png) [@Odermonicon](https://discourse.processing.org/u/Odermonicon)\
**Post date:** [April 5, 2020, 9:11pm UTC](https://discourse.processing.org/t/sort-pimage-array-by-brightness/19423/2 "2020-04-05T21:11:46Z")

</div>

Do something like:

```auto
for (int i = 0; i < bScore.length; i++) {
  bScore[i].save("image"+i);
}

```

PS: this is untested, expect errors.

---

<div class="post-metadata">

**Author:** ![TimoL](https://avatars.discourse-cdn.com/v4/letter/t/9fc29f/32.png) [@TimoL](https://discourse.processing.org/u/TimoL)\
**Post date:** [April 6, 2020, 9:01am UTC](https://discourse.processing.org/t/sort-pimage-array-by-brightness/19423/3 "2020-04-06T09:01:41Z")

</div>

Hmm thanks for the idea. That didn’t work though.

I’ve not used that sort of ‘dot syntax’ with save before.

---

<div class="post-metadata">

**Author:** ![hotfooted](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hotfooted/32/3670_2.png) [@hotfooted](https://discourse.processing.org/u/hotfooted)\
**Post date:** [April 6, 2020, 9:48am UTC](https://discourse.processing.org/t/sort-pimage-array-by-brightness/19423/4 "2020-04-06T09:48:58Z")

</div>

this is terrible but it works and might at least point you in the correct direction.

```auto
PImage [] source; // images to re-order
float [] bScore; //array of brightness "scores" for the images 

void setup () {
  size(20,20);
  source = new PImage[9];
  bScore = new float [9];
  
  for(int i = 0; i < 9; i ++) {
    source[i] = loadImage(sketchPath("data/img"+i+".png") );
    
    bScore[i] = score(source[i]);
  }
  sortImagesByBrightness();
  for (int i = 0; i < bScore.length; i++) {
    source[i].save("data/simg" + i + ".png");
  }
}

void sortImagesByBrightness() {
  int numUnsorted = source.length;
  int max = 0;
  while(numUnsorted > 0) {
    max = 0;
    for(int i = 1; i < numUnsorted; i++) {
      if(bScore[max] < bScore[i]) max = i;
    }
    PImage temp1 = source[max];
    source[max] = source[numUnsorted - 1];
    source[numUnsorted - 1] = temp1;
    
    float temp2 = bScore[max];
    bScore[max] = bScore[numUnsorted - 1];
    bScore[numUnsorted - 1] = temp2;
    
    numUnsorted--;
  }
}

//function to calculate brightness for each image
float score(PImage source) {
  float avg = 0.0;
  source.loadPixels();
  
  for(int i = 0; i < source.pixels.length; i ++) {
    float b = brightness(source.pixels[i]);    
    avg += b;
  }
    avg /= source.pixels.length;  
    return avg; 
}

```

these are the images i used

![img0](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/c/c1a36dc989cf8fead2aefeb294134706897b5f1d.png) ![img1](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/7/7c961c3b44485cc06be763ef296c78c7b2031369.png) ![img2](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/e/e78d3e49bbec434fccab4f226aaacbc40e73aa7b.png) ![img3](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/c/cbe53b9fb8e537aaada9d846c8f9cd56f712ed3c.png) ![img4](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/3/36c92053f251b2a3b4224fbecfbebbe5ed19a148.png) ![img5](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/a/a7b1f5f7edd2b565fdef965b7a1f95e142bfdd1f.png) ![img6](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/1/132a901810676645e5a007a484a12f0d3bf73065.png) ![img7](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/1/147df8fed80145a666fd9b0dbb49494782817e9f.png) ![img8](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/d/db9074a42bfa23a2cf4f8b5ba47c2fe471ded929.png)

---

<div class="post-metadata">

**Author:** ![TimoL](https://avatars.discourse-cdn.com/v4/letter/t/9fc29f/32.png) [@TimoL](https://discourse.processing.org/u/TimoL)\
**Post date:** [July 2, 2020, 7:02am UTC](https://discourse.processing.org/t/sort-pimage-array-by-brightness/19423/5 "2020-07-02T07:02:09Z")

</div>

Thank you so much for your help 🙂

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [July 6, 2020, 2:18am UTC](https://discourse.processing.org/t/sort-pimage-array-by-brightness/19423/6 "2020-07-06T02:18:34Z")

</div>

Here is an additional solution for the same problem.

 ![PImageBrightSort--screenshot](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/3/35757aa7a5e08d2b6ce3fc0f493155d81720eb46.png)

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.

```auto
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](https://discourse.processing.org/t/sort-pvector-array-by-distance/4737/6)

---

<div class="post-metadata">

**Author:** ![TimoL](https://avatars.discourse-cdn.com/v4/letter/t/9fc29f/32.png) [@TimoL](https://discourse.processing.org/u/TimoL)\
**Post date:** [July 9, 2020, 6:12am UTC](https://discourse.processing.org/t/sort-pimage-array-by-brightness/19423/7 "2020-07-09T06:12:23Z")

</div>

Nice one! thanks very much for your help.
