Define all images in a folder-tree

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
ISAWHIM
Veteran
Posts: 318
Joined: Sun Nov 06, 2016 5:34 pm
Contact:

Define all images in a folder-tree

#1 Post by ISAWHIM »

I am having trouble finding code that works, which defines all images in a folder-tree.
SOLUTION IN LAST POST, OF MINE.

I have folder/file format that reflects various things. Folder-names are used for the "locations" and "sub-locations", going up to five levels deep. Then, the file-names are used to identify who is in the scene, and the clothing, moods, times of day... (As opposed to cramming all of this into one folder, with massive names that can't be read at some point.)

An example of my folders/files would be...
../game/maps/town/home/kitchen/sink/noon.jpg (This is the SPOT image, without anyone)
../game/maps/town/home/kitchen/sink/bob casualwashdishes noon.jpg
../game/maps/city/office/lobby/counter/sue workreception morning.jpg

The hierarchy is actually this... (../game/maps/) is ignored...
(main sub area spot) = (town home kitchen sink)
(who [wearing:doing] when) = (bob casualwashdishes noon)

In the game, I "build" the "image to display", (which is not always an exact match), so I need all the tags preserved, from the folders and file-names.

SO... in the two examples, the actual "names" I need them accessed by, is...
scene town home kitchen sink bob casualwashdishes noon
scene city office lobby counter sue workreception morning

Looking at the codes, they look like they should work, but I can't get them to work. The codes are all old, and I can't even get the direct examples to work, or they are just too specific to one individuals needs, and only sort-of work, for my needs. (Help-files are kind-of vague, so there is only so much I can actually "look up", to see where they may be failing.)

I sort-of need it to be a function, so the code is not a giant nested tree of IF and FOR loops.

This is the old code that I found, which was (as far as I can see), setup to function as I need. But, for some reason, it doesn't function as desired, as it describes. (I only modified the code to remove the "flip image" function, which I do not need.)

I put this in the [options.rpy] file, which has a loading-order of -10, but that only matters for when it is read. "early", is specific to python, but I am not sure if that is even supported by RenPy.

Code: Select all

init python early:
    #import os #[??? not needed, unsure, I added this in, as found in another set of code. I didn't get any errors without it. Thought it may be why it wasn't working.]
    def define_images(imageFolder, excludeFolders=0):
            for path in renpy.list_files():
                if path.startswith(imageFolder + "/"):
                    path_list = path.split("/")
                    path_list[-1] = os.path.splitext(path_list[-1])[0]
                    path_list = tuple(path_list[excludeFolders:])
                    renpy.image(path_list, path)
The code to call it, resides in the [script.rpy] file location, near the beginning. The loading-order for that file is 0.
$define_images('maps/', 1)

Which tells it to start looking in the "maps" folder, from the "games" folder... I also tried ('games/maps/', 2), and tried moving the "maps" folder into the "images" folder, with no luck.

A few specifically tell it to look for PNG, JPG and JPEG files... Some codes just said IMAGE_TYPES or something like that... I tried this with both PNG and JPG images, and nothing actually worked in any of the codes.

I would have used the auto-define function from RenPy (just adding them to the images directory, in the folders), but that has an odd demand of needing to repeat the folder-structure, within the name-structure, which is just redundant and stupid... "../eileen/smile/greenshirt/eileen_smile_greenshirt.png" = "eileen smile greenshirt".

This will be thousands of images... I don't want to type this all out, by hand, twice, per image... and burden everyone to also download that wasteful image-data too.

I don't know why we can't just use an image-path as the images to load, as a variable, when needed. Such an odd demand that they must be individually defined.

scene "myfile.jpg"

That is all anyone wants... or

$my_location = $loc_main + $loc_sub + $loc_... ... ...
scene $my_location

Which is essentially what I am trying to replicate in the "needs an image object" or "displayable"... scene-call-function

Just some side-notes... Each folder also has an associated image, related to the actual "map" that it displays... Used for the image-buttons, where you select the locations, per map-level. So those will also be "indexed" as displayables too.

../maps/bg.jpg <-(image of all main locations, as the "map")
../maps/town.jpg <-(icon of the "town" DEFAULT) [has an associated folder]
../maps/city.jpg
../maps/town selected.jpg <-(icon of the "town" SELECTED) [has an associated folder]
../maps/town hover.jpg
../maps/town/bg.jpg <-(BG image of the "town", displayed on screen.)
../maps/town/home.jpg <-(icon of the "home" DEFAULT) [has an associated folder]
../maps/town/home selected.jpg <-(icon of the "home" SELECTED) [has an associated folder]
../maps/town/store.jpg
../maps/town/store/bg.jpg

etc...

Where as the images, at each nested folder-level, are just specific to "something being displayed", at that level. Like "bob casualwaiting noon.jpg", "bob workcounter noon.jpg", "bob nudeshoweringhappy night.jpg"...

Bob (as a PNG overlay) may be in just the "house BG" (sub-location), or just in the "house bathroom BG" (area of sub-location), or "house bathroom shower BG" (spot in an area, in a sub-location)

When there is no specific "deeper nested image", the image from the higher-level loads, as that is generic to all the sub-locations in the tree. Which is why I need the image-tags retained.
Last edited by ISAWHIM on Sun Apr 15, 2018 12:36 am, edited 1 time in total.

User avatar
ISAWHIM
Veteran
Posts: 318
Joined: Sun Nov 06, 2016 5:34 pm
Contact:

Re: Define all images in a folder-tree

#2 Post by ISAWHIM »

Follow-up...

I made this "manually setup"... like so... (Right in the script.rpy file, in the start-section.)

Code: Select all

    init python:
        for path in renpy.list_files():
            if path.startswith("maps" + "/"):
                excludeFolders = 1
                path_list = path.split("/")
                path_list[-1] = os.path.splitext(path_list[-1])[0]
                path_list = tuple(path_list[excludeFolders:])
                renpy.image(path_list, path)
Now, without it being a "function"... It half-works...

It will correctly setup files without a "space" in the name.
../maps/home/noon.jpg <--(loads fine, defined correctly, "home noon")
../maps/home/bob casualsitting noon.jpg <--(Does not seem to be loaded as "home bob causalsitting noon")
*** There will never be a folder named "bob"... but... if there is... it will contain all images associated with "bob", and "bob" would then be removed from the image-names. I just don't want a billion folders, all nested, unless the image-management gets crazy in a specific folder. Also, the fifth-level is for special variations, which is not common in all folders. Just as not all areas have "spots" (the fourth-level depth).

(It can see them, because I saw them as raw text, when I put a renpy.say() into the loop, before moving it to an init-python block.)

Code: Select all

    python:
        for path in renpy.list_files():
            if path.startswith("maps" + "/"):
                renpy.say(G, path)
I suspect it is the path.split() function, which is the issue. It splits the path only... using that to identify the image. Instead of ALSO including the "full file-names" (with the spaces in them), as the image-define listing.

I think I answered my own question... I just don't know, for some reason, why my brain is not unwrapping what "needs to be done"...

Looks like it is doing this...

define PATH(split) as "IMAGE-PATH/FILE-NAME"

But the PATH(split), is only the actual PATH tag words it is using... not including the FILE-NAME words too... or maybe it is only using the last word attached to the PERIOD "bob casualgreet noon.jpg" -> "noon" (Because it sees the "image" as just "noon.jpg")

I am unsure, because it throws everything into lists and tuples, at that point, and I don't know how to "print that", easily, to view what it is placing in those arrays.

I think it is doing this... as the "filename tags"
(town) + (home) + (kitchen) + (sink) + (noon)
instead of this...
(town) + (home) + (kitchen) + (sink) + (bob casualwashingdishes noon)
or this...
(town) + (home) + (kitchen) + (sink) + (bob) + (casualwashingdishes) + (noon)

The image locations should not be changed, as they are the actual "paths", as a whole. So I assume it is in the "image-define", (tag-names), that it is messing-up. Like RenPy's internal code doesn't think that spaces are valid within file-names, or it is converting them to something other than a space, and thus, not a space, when joined.

In that case, it IS doing this...
(town) + (home) + (kitchen) + (sink) + (bob casualwashingdishes noon)

But (bob casualwashingdishes noon) is not a possible "tag-word" to use in SCENE... Because there is no way to represent "spaces", because spaces are the seperation value, for the [individual] tag-words... So it is looking for (bob) + (casualwashingdishes) + (noon)... and no way to actually look for the actual "tag-word" (bob casualwashingdishes noon) is possible. For the image "bob casualwashingdishes noon.jpg"

User avatar
ISAWHIM
Veteran
Posts: 318
Joined: Sun Nov 06, 2016 5:34 pm
Contact:

Re: Define all images in a folder-tree

#3 Post by ISAWHIM »

Another follow-up...

So the path-split is doing what I obviously expected... Tested by joining it back with ":" symbols...
../maps/town/bob casual noon.jpg --> (maps:town:bob casual noon.jpg)

I assume that the next line is where it is breaking... Doing one of two things...
Turning (maps:town:bob casual noon.jpg)
into... (maps:town:bob) {Throwing-out "casual noon", because that is seen as the image extension "casual noon.jpg" of the word "bob"}
or into... (maps:town:noon) {Throwing-out "bob casual", and keeping just "noon.jpg", as the rest of the words are not seen as being attached to ".jpg"}

or... It is converting the "spaces", into some unicode, or %20, like a web-browser, which can't be {normally} addressed as part of a "image tag word". As opposed to ALSO creating tag-words from the individual "text-safe" words.

So now I am trying to see what the following line is breaking in the process... Also going to try a double-split, to strip the spaces first.

User avatar
ISAWHIM
Veteran
Posts: 318
Joined: Sun Nov 06, 2016 5:34 pm
Contact:

Re: Define all images in a folder-tree

#4 Post by ISAWHIM »

Another follow-up...

I got the correct "text output" now... But the "function" just doesn't work...

Test-code... (Modified version of the function, to display the text-output on the screen, as a character.)

Code: Select all

    python:
        #def define_images(imageFolder, excludeFolders=0):
        excludeFolders=1
        imageFolder="maps"
        for path in renpy.list_files():
            if path.startswith(imageFolder):
                path_list = ("/".join(path.split())).split("/")
                path_list[-1] = os.path.splitext(path_list[-1])[0]
                path_list = tuple(path_list[excludeFolders:])
                y = " ".join(path_list)
                renpy.say(G, y)
Text-output is "town home kitchen bob casualgreet noon"...
Path-text is "maps/town/home/kitchen/bob casualgreet noon.jpg"

So, it should be creating the IMAGE("town home kitchen bob casualgreet noon", "maps/town/home/kitchen/bob casualgreet noon.jpg")
That is exactly matching my manually typed "Image" code, that previously existed, before I commented-out the code. Though, my "folder" was actually in the "images" folder, not the "game" root folder. Renpy didn't seem to care about the actual location, as long as it was in one of those two locations.

I tried moving the "maps" folder, back to the "images" folder, and that doesn't make it work... With the adjusted function call parameters ("images/maps", 2)

So it is not working... for some reason.

The actual "function"... I tried setting it everywhere... in every file...

Code: Select all

init python:
    import os
    def define_images(imageFolder, excludeFolders=0):
        for path in renpy.list_files():
            if path.startswith(imageFolder):
                path_list = ("/".join(path.split())).split("/")
                path_list[-1] = os.path.splitext(path_list[-1])[0]
                path_list = tuple(path_list[excludeFolders:])
                renpy.image(path_list, path)
The image exists, the path exists, the function is "called" in scripts.rpy
Tried various methods...

Code: Select all

#Tried this...
python:
    define_images("maps", 1)
    
#Tried this...
$define_images("maps", 1)

#Tried this...
$ define_images("maps", 1)

#Tried this...
call define_images("maps", 1)

#Tried this...
define_images("maps",1)
# throws an error, saying "Expected statement"
But none of the images load... Only the last one gives any kind of error. It is as if they are not actually defined, as images, again/still.

User avatar
ISAWHIM
Veteran
Posts: 318
Joined: Sun Nov 06, 2016 5:34 pm
Contact:

Re: Define all images in a folder-tree

#5 Post by ISAWHIM »

Renpy isn't even attempting to "call" the function, or run the code.

I used totally made-up names to things that didn't exist, and Renpy doesn't even throw an error...
I would expect, at least, something saying that "someMadeUpName" doesn't exist... or "has no parameters"... or something.

Code: Select all

call someMadeUpName("randome stuff", 3434)
$ someMadeUpName("randome stuff", 3434)
$someMadeUpName("randome stuff", 3434)

python:
    someMadeUpName("randome stuff", 3434)
Renpy is totally happy just not-executing that line, at all, as if it doesn't even exist. It's no wonder that the code isn't working, it isn't even attempting to run it.

There is one time it will give an error... if I put it directly after the def code, in the "init python"... Then it says, "can't define images in the INIT phase"... Apparently, that is the only time it is actually trying to run the code.

I even tested it by adding... renpy.say("","hello"), in the def code... that should throw an error, because it also can't "say" anything without a "window", in the "init phase".

So something is buggy in RenPy, at the moment.

User avatar
ISAWHIM
Veteran
Posts: 318
Joined: Sun Nov 06, 2016 5:34 pm
Contact:

Re: Define all images in a folder-tree

#6 Post by ISAWHIM »

Finally... I got it...

RenPy was just buggin-out, for a majority of the time. Needed to update and reboot...

Final code that works for me. Placed at the beginning of script.rpy

Code: Select all

init python:
    def defImages(iDir, exDir=0):
        iDir = iDir.strip("/") + "/"
        for iPath in renpy.list_files():
            if iPath.startswith(iDir):
                if (iPath.lower()).endswith(".png") or (iPath.lower()).endswith(".jpg"):
                    pList = ("/".join((iPath.lower()).split())).split("/")
                    pList[-1] = os.path.splitext(pList[-1])[0]
                    pList = tuple(pList[exDir:])
                    renpy.image(pList, iPath)

    defImages("/maps/", 1)
Works with spaces in the image-names, and correctly "names" the image tags, with all lower-case names. Only the jpg and png files. Which is the only two I use for this specific set. I added a little "/folder/" format protection, so it works when people, including myself, type in a standard "/folder/format/". It will still also match "this", as s folder, and not match it to "this.jpg", in the root folder, or "/this folder/", or "this file.jpg".

Also a protection for unmatching "image.ext"... like ".Png", and ".PNG", where it might not "match".

Post Reply

Who is online

Users browsing this forum: Google [Bot]