As I pull each one out in order I get 0.png, 1.png, 100.png etc. - not what I want, I want 0.png, 1.png, 2.png etc. Is there something that can be used in sort to resolve this or an alternative way of sorting that will correct this?
This is a common problem that has no library solution I’ve ever encountered. I’ve always seen it solved by writing a custom sort function that parses the numbers out of the file names and uses them to determine the order.
You can also use one of the many free utility tools that let you rename files in batch.
You could easily add leading zeros to your number and use classic array sort to sort your files.
My approach to this would be to first order each String image filepath by length and then by its natural order. So, first you have all images/16/1.png … to images/16/9.png and so on.
In java 8 or above this could be accomplished using:
But I don’t know with which version of java you are working on. If it is below 8 then you have to do a customized function but the logic might be the same
Using Java 11 in Processing 4 so your comparator solution is the same one I’ve hit on. Your version here won’t work for me as is because you are using a String[] and I’m using a File[], which I didn’t specify, so it chokes on String::length. I thought something like str(File)::length but no - unclear how to pull out each file and convert is to a string so I can use length.
For everyone else telling me to rename files, this isn’t an option for me. I won’t be in control of the folder being traversed but apart from that leading zeros is not a great solution as it sets a count upper limit for the file name i.e. they have to stop at say 9999.png etc.
import java.io.File;
import java.io.FileFilter;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
String imagespath;
File[] images;
void setup()
{
size(480, 672);
// Path to images folder
imagespath = sketchPath() + "/images/";
File dir = new File(imagespath);
// Get an array of all folders inside images folder
File[] folders = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isDirectory();
}
});
// Randomly select a folder
int folderlength = folders.length;
int i = int(random(folderlength));
dir = new File(folders[i].getAbsolutePath() + "/");
// Get an array of all png images
images = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().toLowerCase().endsWith(".png");
}
});
//Arrays.sort(images);
//print(Arrays.toString(images) + "\n\n");
Comparator.comparingInt(String::length).thenComparing(Comparator.naturalOrder()));
print(Arrays.toString(images));
exit();
}
According to Oracle java documentation, File has a toString() method, which returns the pathname string of this abstract pathname. Maybe you need to invoke this method instead of str(). I tried running your code but since I don’t have the structure or images I can’t test it.
Hope it helps!
If I have the time I will try to create random images to test your code again. But I highly doubt that this is something that cannot be solved with all Java IO File and NIO classes.
Yes the natural sorting works (minus the extra typo bracket at the end of Arrays.sort()). I’m looking into the toString() method you mentioned in File. Would be nice/tidier to keep it as a File[] and just use the strings temporarily while sorting but failing that this will be my fall back solution. Many thanks for your help!