Home > Software design >  Rename images keeping the old name and adding prefix which corresponds to the order of a list
Rename images keeping the old name and adding prefix which corresponds to the order of a list

Time:10-05

I have a list List=["cat", "dog", "horse", "",...] and I have images in ./images/folder/ which contains images files:

image0.png
image100.png
image2.png
...

Note images are not ordered in folder and os.listdir(path) show:

'image118.png'
'image124.png'
'image130.png'
...

My expectation is to receive files with these names.

image0_cat.png
image1_dog.png
image2_horse.png
...

This is my current code:

    import os
    path= './images/folder/'
    
    for label, filename in zip(my_label,os.listdir(path)):
        if os.path.isdir(path):
            os.rename(path   "/"  filename, path   "/"  filename   "_"   str(label)   ".png")

But the output is different than my expectations.

Output:

image0.png_horse.png
image1OO.png_horse.png
image2.png_cat.png
...

CodePudding user response:

If you know that the name of the images is always image<nb>.png, with ranging from 1 to len(my_label) without interruptions then you can generate the names directly instead of scanning through the folder:

for i, label in enumerate(my_label):
    filename = f"image{i 1}"
    old_file = os.path.join(path, filename   ".png")
    new_file = os.path.join(path, filename   f"_{label}.png")
    os.rename(old_file, new_file)

where os.path.join is the preferred way to actually generate file paths (it takes into account the "/", and different OS systems)

Otherwise, you will need to first parse the numbers from the list of files:

numbers = []
for image in os.listdir(path):
    number = os.path.basename(image)[len("image"):-len(".png")]
    numbers.append(int(number))

then you can sort that list:

sorted_numbers = sorted(numbers)

And finally, you can iterate through that list, to generate the filenames (that you know should exist), similarly to the previous method:

for number, label in zip(sorted_numbers, my_label):
    filename = f"image{number}"
    old_file = os.path.join(path, filename   ".png")
    new_file = os.path.join(path, filename   f"_{label}.png")
    os.rename(old_file, new_file)

Assuming that you have the right number of labels for your images.

CodePudding user response:

Have you tried : filename.split(".")[0] to get the root of your filename? Maybe not the finest solution but..

CodePudding user response:

You can use this snippet:

import os
from pathlib import Path

path = './images/folder/'
my_label = ["cat", "dog", "horse", "",...]

for label, filename in zip(my_label, os.listdir(path)):
    if os.path.isdir(path):
        fn = Path(filename)
        os.rename(os.path.join(path, filename),os.path.join(path, f"{fn.stem}_{label}{fn.suffix}"))

This code is little more universal because you use original extension instead hardcoded ".png". You can read more about pathlib here: docs

  • Related