chaiNNer-org / chaiNNer

A node-based image processing GUI aimed at making chaining image processing tasks easy and customizable. Born as an AI upscaling application, chaiNNer has grown into an extremely flexible and powerful programmatic image processing application.
https://chaiNNer.app
GNU General Public License v3.0
4.46k stars 277 forks source link

Run chainner with parameters & associate parameters with nodes #2242

Open TheOverpassArsonist opened 11 months ago

TheOverpassArsonist commented 11 months ago

Motivation I picked up ChaiNNer yesterday and, while I love how configurable it is, for doing basic/conceptually-simple tasks (i.e. : "upscale this video") it can take a while to get started. Even after you make and save a chain to complete a task it's still more tedious to use that chain than drag-and-dropping a video file into a box and clicking run.

Description I believe it would be a massive feature add to be able to use ChaiNNer in some automated way. For instance, being able to run chainner --hide --startnow ~/Chains/UpscaleImage.chain Image.png would pipe Image.png into a designated 'load image' node that is associated with the first parameter after the chain (this would have to be configured by the user on a per-chain basis) and then automatically start the chain and run it to completion without showing the main window. While this would already be a massive feature-add because it would mean users could do things that no other upscalers offer (for instance in Linux you could create a .desktop file for that command, add it as an "Open as" option for .png files, and then literally just right click any .png file on your computer and upscale it) it would also be easily expandable with new nodes. For instance there could be a "bulk iterate image" node which takes in an arbitrary number of images as arguments. (or potentially do some check to see if lots of images got passed to unique chainner instances and reduce them down to a single instance that gets iterated through. Due to how bulk-file-opens are handled on every OS I'm aware of, instead of passing through each file as a parameter to the command instead each file would be passed individually as the 1st argument. This could be fixed with another script to parse through the inputs though, so it's not fatal if Chainner can't automatically detect bulk openings like that - it would just mean that if you want to do something like that it takes a bit more work on your end to implement) Another possible extension would be adding a % done bar to the OS. (In windows this might require a tray icon or something but in linux progress-bar notifications are native)

The benefit here is that, aside from those possible further extensions to improve the functionality, this is just re-using aspects that are already implemented. The MVP of this would just be a way for Chainner to associate command line arguments with input nodes and for chainnr to be able to run silently & automatically. With this functionality Chainner could be both more usable and well integrated while being more functional than any alternatives avaliable, even for simple tasks.

The part of implementing the MVP of this would have to be the association of command line arguments with nodes, but aside from that there isn't much work that would need to be done. Even without the ability to run Chainnr silently just the ability to associate input parameters with nodes and automatically start could still mean people could essentially create their own custom utilities to perform specific operations on files easily.

joeyballentine commented 11 months ago

This is already possible. Take a look here: https://github.com/chaiNNer-org/chaiNNer/blob/main/docs/cli.md

TheOverpassArsonist commented 11 months ago

This is already possible. Take a look here: https://github.com/chaiNNer-org/chaiNNer/blob/main/docs/cli.md

as far as I can tell that's only windows, (at least I can't find any information on non-windows CLI and it doesn't have a man-page) and it relies on importing a .json instead of taking direct CLI arguments which means that you'd have to write a custom .json parser to accept and convert standard CLI arguments into the right format on a per-chain basis. My suggestion is more specifically there being a way to set some nodes in a chain to have a parameter input, meaning if you had a chain with one load-image node and had it set to parameter 1 (or 0, whichever you want to start indexing at first.) then you could run

chainner /path/to/chain /path/to/file

and it would plug "/path/to/file" into whatever node is associated with parameter 1. If you created a shortcut or desktop file that already contained 'chainner /path/to/chain/` then you could add that into your OS as an option to open files with to basically have right-click integration. (for instance you can right click on a .png, then move to "open with", and see other applications you could open the file with like photoshop, gimp, a photoviewer, etc.) Behind the scenes since opening an application "with" a file just means passing that file's path to the application as a parameter, being able to configure nodes to accept standard input parameters would mean users can basically get custom right click integration with minimal techincal knowledge. (even near-zero technical knowledge if the creation of .lnk or desktop files linking to specific chains is automated)

While it would be possible for users to write a .json parser to automatically generate .json inputs for chainner based on CLI parameters, that puts this functionality well outside of the technical abilities of most users. It's fairly simple to copy a shortcut or .desktop file and copy the path to a chain, give it a name, etc. but writing an entire custom json parsing script is a far bigger ask. Plus, it's a simple enough process that automatically creating those shortcuts software side wouldn't be very hard either, meaning if parameter-based inputs were added this could be doable from the GUI as well. (at least for .desktop files, admittedly the last time I had to mess with a .lnk file it was not fun, although I didn't exactly bother to learn how to do it properly either so that might have been my own fault) For instance under the file tab there could be a "export as automated" button which would create a .lnk or .desktop file that already has the path to the chain added. If that's the case then all the user would have to do is add it to their OS as an "open with" option and they'd never have to understand anything more technical about how it works under the hood. I'll grant that Chainner is a decently technical application, but the skillset it expects has much less to do with programming or computer-technical knowledge and a lot more to do with image manipulation & AI knowledge specifically.

While I'll admit I didn't notice the CLI functionality (I checked for a man page and did some googling but didn't notice the doc page) only accepting .json inputs instead of being able to map nodes to parameter inputs severely limits non-technical users' ability to add these sorts of automations. A photographer for instance could pick up Chainner decently well within a few hours, export an automated-chain, and setup their OS to let them automatically upscale, fix imperfections, etc. their images without ever needing to even know what a command line parameter is. Relying on exclusively .json inputs however means if a user isn't already technical enough to write their own parser they just can't do it and most people won't be willing to learn how to do that.

I'm primarily on linux currently but I have a dual boot I might be able to test this idea on as a proof-of-concept. I haven't looked over the internals enough for me to confidently make a PR, but I should be able to draft up a basic generalized json parser which could do a bit like what I'm suggesting. (albiet more clunky) Depending on how busy the next few days are I should be able to have a POC done within anywhere from a few days to a week.

RunDevelopment commented 11 months ago

as far as I can tell that's only windows

Chainner is cross-platform. I documented it for Windows because I use Windows (so I know that the commands are correct), but it should work for Linux/Mac as well.

My suggestion is more specifically there being a way to set some nodes in a chain to have a parameter input, meaning if you had a chain with one load-image node and had it set to parameter 1 (or 0, whichever you want to start indexing at first.

Not a bad idea. In fact, I think we could make your idea into something better than the current system.

Here's what I'm thinking of: to make this happen, we basically just need to store a list of overwrite IDs inside the .chn file. When running a command (e.g. chainner my-chain.chn image.png 4 "foo"), it would then use this list to assign command line arguments to inputs.

So how would a user add inputs to this list? I'm thinking of reusing the logic for the "Copy Input Overwrite Id" context menu entry for inputs. We could simply add another context menu entry next to it called "Add to CLI parameters". Users can now add inputs to the list of CLI-overwritable-inputs. To edit the list directly, we could add a button/menu entry that opens a simple popup. That popup would just display the list and allow users to reorder input IDs and remove inputs. I'm thinking of a super simple UI like this:

image

Additionally, we could also give parameters names in the UI, so users can do something like --save-name="cool name" in the command line.

What do you think?

TheOverpassArsonist commented 11 months ago

as far as I can tell that's only windows

Chainner is cross-platform. I documented it for Windows because I use Windows (so I know that the commands are correct), but it should work for Linux/Mac as well.

My suggestion is more specifically there being a way to set some nodes in a chain to have a parameter input, meaning if you had a chain with one load-image node and had it set to parameter 1 (or 0, whichever you want to start indexing at first.

Not a bad idea. In fact, I think we could make your idea into something better than the current system.

Here's what I'm thinking of: to make this happen, we basically just need to store a list of overwrite IDs inside the .chn file. When running a command (e.g. chainner my-chain.chn image.png 4 "foo"), it would then use this list to assign command line arguments to inputs.

So how would a user add inputs to this list? I'm thinking of reusing the logic for the "Copy Input Overwrite Id" context menu entry for inputs. We could simply add another context menu entry next to it called "Add to CLI parameters". Users can now add inputs to the list of CLI-overwritable-inputs. To edit the list directly, we could add a button/menu entry that opens a simple popup. That popup would just display the list and allow users to reorder input IDs and remove inputs. I'm thinking of a super simple UI like this:

image

Additionally, we could also give parameters names in the UI, so users can do something like --save-name="cool name" in the command line.

What do you think?

That's basically what I was thinking yeah, although it would probably also be a good idea to also automatically assume that if a chain has only 1 input it should be taken as the first parameter. I do think named overrides should still be an option for more advanced automation use-cases like you say but simple positional CLI usage as an option just adds a lot of possibilities for easy integration. (again, especially if it's automated within Chainner itself so people don't even have to understand how any of it's working to use it) In terms of automation another extension which could be useful would be to have nodes to accept other input parameters, for instance a way to input a number, a way to input a string, etc. so things like chainner ~/upscaleimage.chain 1.05 ~/EnhancedPictures/ ~/Pictures/Picture1.jpg could work as well. That example for instance would be taking some number input, some directory, and finally the input image to modify. This could possibly represent an upscale command that also performs some enhancement to the image based on the provided number after upscaling it and saving it to ~/EnhancedPictures. Personally I mainly use Chainner for simply upscaling, but I could see the ability to input other values like that making a lot more advanced automation possible.

A bit off topic but I did test it on linux and it does work on there as well, I just figured that since it didn't have a man page and the doc mentioned windows specifically and used windows terms it was a windows only feature for now. Also, while I was working on my proof of concept parser (before I checked back here) I also noticed directories are treated seperately from text strings, is there a reason for that behind the scenes? It's not strictly related to positional CLI but it's something I noticed while setting up a test case for my parser. (I was trying to output images into ./upscaled/ and noticed I couldn't just append "upscaled/" to the directory of the loaded image. The subdirectory field is an option, but it just seems weird to not be able to arbitrarily modify directories as strings. Even in my testcase above I sort of just took that for granted to illustrate the idea)

joeyballentine commented 11 months ago

I also noticed directories are treated seperately from text strings, is there a reason for that behind the scenes?

Easier validation that directories are valid when the user isn't able to append garbage to it. We also wanted to have directory specific nodes (there's an open issue for it) it's just nobody's done it yet