2

Main goal: Converting images and then making a video (using videoshow) of the converted images in a specific order.

Problem: images are unordered.

Expected: have a file path list sorted just like I see in finder, by the filenames.

Reality: I'm getting a non-sorted list of file paths. Since I am using videoshow to generate a video, this is a serious problem for me because images are being added unordered.

Tries:

I am using asynchronous code and I think this can be the problem, although I am currently using fs.readdirSync()...

I have tried using glob module but it didn't worked either. I have tried putting an await keyword before everything related to filename reading but it didn't worked either.


Code

    const state = require("./state.js");
    const fs = require("fs");

    const originalDir = "./content/images/";
    const resizedDir = "./content/images/resized/";

    async function robot() {
      const content = state.load();

      await acquireImages();
      console.log(content.images)

      async function acquireImages() {
            originalFiles = fs.readdirSync(originalDir);
            imagesList = [];
            resizedImagesList = [];
            originalFiles.forEach(file => {
                if (file.slice(-3) == "png") {
                    imagesList.push({
                        filePath: originalDir + file,
                        fileName: file.slice(0, -8)
                    });
                }
            });

            await imagesList.forEach(image => convertImage(image));

            await populateImageList();
        }

      async function populateImageList() {
            resizedFilenames = await fs.readdirSync(resizedDir);
            resizedImagesList = [];
            for (const file of resizedFilenames) {
                if (file.slice(-3) == "png") {
                    resizedImagesList.push(resizedDir + file);
                }
            }
            content.images = resizedImagesList;
        }
    }

    module.exports = robot;

Expected Output:

Just like in Finder order.

expected output

Current Output:

[ '10_123.5-126.6(2)(converted).png',
  '11_123.5-126.6(3)(converted).png',
  '12_139.6-139.8(1)(converted).png',
  '13_139.6-139.8(2)(converted).png',
  '14_139.6-139.8(3)(converted).png',
  '15_166.1-170.6(1)(converted).png',
  '16_166.1-170.6(2)(converted).png',
  '17_166.1-170.6(3)(converted).png',
  '18_188.8-189.4(1)(converted).png',
  '19_188.8-189.4(2)(converted).png',
  '1_113.3-113.7(1)(converted).png',
  '20_188.8-189.4(3)(converted).png',
  '21_6.6-7(1)(converted).png',
  '22_6.6-7(2)(converted).png',
  '23_6.6-7(3)(converted).png',
  '24_68.5-68.6(1)(converted).png',
  '25_68.5-68.6(2)(converted).png',
  '26_68.5-68.6(3)(converted).png',
  '27_77.1-77.4(1)(converted).png',
  '28_77.1-77.4(2)(converted).png',
  '29_77.1-77.4(3)(converted).png',
  '2_113.3-113.7(3)(converted).png',
  '30_81.7-81.9(1)(converted).png',
  '31_81.7-81.9(2)(converted).png',
  '32_81.7-81.9(3)(converted).png',
  '33_87.3-87.4(1)(converted).png',
  '34_87.3-87.4(2)(converted).png',
  '35_87.3-87.4(3)(converted).png',
  '36_96.3-96.9(1)(converted).png',
  '37_96.3-96.9(2)(converted).png',
  '38_96.3-96.9(3)(converted).png',
  '39_undefined-undefined(1)(converted).png',
  '3_116.7-118.6(1)(converted).png',
  '40_undefined-undefined(2)(converted).png',
  '41_undefined-undefined(3)(converted).png',
  '4_116.7-118.6(2)(converted).png',
  '5_116.7-118.6(3)(converted).png',
  '6_121.6-122.3(1)(converted).png',
  '7_121.6-122.3(2)(converted).png',
  '8_121.6-122.3(3)(converted).png',
  '9_123.5-126.6(1)(converted).png' ]

1 Answer 1

2

You need to sort the array returned by fs.readdirSync. Normal sort won't cut it, you'll need a form of natural-sort to get the ordering you want.

If you have have a node build with Intl support, you could use something like this:

let arr = ["10_123.5-126.6(2)(converted).png","11_123.5-126.6(3)(converted).png","12_139.6-139.8(1)(converted).png","13_139.6-139.8(2)(converted).png","14_139.6-139.8(3)(converted).png","15_166.1-170.6(1)(converted).png","16_166.1-170.6(2)(converted).png","17_166.1-170.6(3)(converted).png","18_188.8-189.4(1)(converted).png","19_188.8-189.4(2)(converted).png","1_113.3-113.7(1)(converted).png","20_188.8-189.4(3)(converted).png","21_6.6-7(1)(converted).png","22_6.6-7(2)(converted).png","23_6.6-7(3)(converted).png","24_68.5-68.6(1)(converted).png","25_68.5-68.6(2)(converted).png","26_68.5-68.6(3)(converted).png","27_77.1-77.4(1)(converted).png","28_77.1-77.4(2)(converted).png","29_77.1-77.4(3)(converted).png","2_113.3-113.7(3)(converted).png","30_81.7-81.9(1)(converted).png","31_81.7-81.9(2)(converted).png","32_81.7-81.9(3)(converted).png","33_87.3-87.4(1)(converted).png","34_87.3-87.4(2)(converted).png","35_87.3-87.4(3)(converted).png","36_96.3-96.9(1)(converted).png","37_96.3-96.9(2)(converted).png","38_96.3-96.9(3)(converted).png","39_undefined-undefined(1)(converted).png","3_116.7-118.6(1)(converted).png","40_undefined-undefined(2)(converted).png","41_undefined-undefined(3)(converted).png","4_116.7-118.6(2)(converted).png","5_116.7-118.6(3)(converted).png","6_121.6-122.3(1)(converted).png","7_121.6-122.3(2)(converted).png","8_121.6-122.3(3)(converted).png","9_123.5-126.6(1)(converted).png"];

let collator = new Intl.Collator(undefined, {
  numeric: true,
  sensitivity: 'base'
});
arr.sort(collator.compare);

console.log(arr);

Alternatively you could also use a natural-sort library like e.g. javascript-natural-sort:

let arr = ["10_123.5-126.6(2)(converted).png","11_123.5-126.6(3)(converted).png","12_139.6-139.8(1)(converted).png","13_139.6-139.8(2)(converted).png","14_139.6-139.8(3)(converted).png","15_166.1-170.6(1)(converted).png","16_166.1-170.6(2)(converted).png","17_166.1-170.6(3)(converted).png","18_188.8-189.4(1)(converted).png","19_188.8-189.4(2)(converted).png","1_113.3-113.7(1)(converted).png","20_188.8-189.4(3)(converted).png","21_6.6-7(1)(converted).png","22_6.6-7(2)(converted).png","23_6.6-7(3)(converted).png","24_68.5-68.6(1)(converted).png","25_68.5-68.6(2)(converted).png","26_68.5-68.6(3)(converted).png","27_77.1-77.4(1)(converted).png","28_77.1-77.4(2)(converted).png","29_77.1-77.4(3)(converted).png","2_113.3-113.7(3)(converted).png","30_81.7-81.9(1)(converted).png","31_81.7-81.9(2)(converted).png","32_81.7-81.9(3)(converted).png","33_87.3-87.4(1)(converted).png","34_87.3-87.4(2)(converted).png","35_87.3-87.4(3)(converted).png","36_96.3-96.9(1)(converted).png","37_96.3-96.9(2)(converted).png","38_96.3-96.9(3)(converted).png","39_undefined-undefined(1)(converted).png","3_116.7-118.6(1)(converted).png","40_undefined-undefined(2)(converted).png","41_undefined-undefined(3)(converted).png","4_116.7-118.6(2)(converted).png","5_116.7-118.6(3)(converted).png","6_121.6-122.3(1)(converted).png","7_121.6-122.3(2)(converted).png","8_121.6-122.3(3)(converted).png","9_123.5-126.6(1)(converted).png"];


arr.sort(naturalSort);
console.log(arr);
<!-- ignore this -->
<script>module = {};</script>
<script src="https://unpkg.com/[email protected]/naturalSort.js"></script>
<script>naturalSort = module.exports;</script>

In your code example it could be integrated like this:

async function acquireImages() {
  let originalFiles = fs.readdirSync(originalDir);
  let collator = new Intl.Collator(undefined, {
    numeric: true,
    sensitivity: 'base'
  });
  originalFiles.sort(collator.compare);
  // ...
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.