ImgScal

Automate image processing programmatically.

Documentation Information


Supported Encodings

Encodings are split into basic and unique. Basic encodings are images without any additional functionality. Unique encodings are images that have additional functionality that isn't covered by io.decode and io.encode.


Basic Encodings Supported
  • PNG - .png
  • JPEG - .jpg, .jpeg
  • BMP - .bmp
  • TIFF - .tiff, .tif
  • WebP - .webp

Unique Encodings Supported
  • PNG - .png
    • Additional support for encoding and decoding with data stored in custom chunks.
    • Uses the chunk type iscL
  • FAVICON - .ico, .cur
    • When decoded using the generic io.decode function, only the largest image will be returned.
    • When encoded using the generic io.encode function, only a single image can be provided, and will always be of the ICO type.
  • GIF - .gif
    • When decoded using the generic io.decode function, only the first frame will be returned.
    • When encoded using the generic io.encode function, will not include animation.
Workflow Setup
The workflow.json file.

This is where a workflow is defined, generally each workflow.json should have it's own directory.

{
    "$schema": "https://gist.githubusercontent.com/ArtificialLegacy/9711f20511e76b519aedb729a6762b9f/raw/de77e999654060a38d7a4e7eea8aeb4f5ee1273e/imgscal_workflow.json"
    "name": "",
    "author": "",
    "version": "",
    "api_version": 1,

    "desc": "",
    "desc_long": [
        "",
        ""
    ],

    "workflows": {
        "*": "?.lua",
        "other": "?.lua"
    },

    "cli_workflows": {
        "*": "?.lua"
    }
}
  • name - This is the name of the workflow, it should not include spaces. Using all lowercase should also be preferred.
  • api_version - This is used to determine compatibility. In stable versions backwards compatibility is guaranteed, so this value must be equal to or less than the API version in the tool.
  • desc_long - This can be used when the description is long that it becomes awkward to write on a single line, once parsed it will be appended to desc with each string being joined with a space.
  • workflows - This is where entry points can be defined for the workflow selection menu.
  • cli_workflows - This is where entry points can be defined for directly calling from the command-line.

An entry point is mapped in the following ways:

  • When an entry point is named using "*", it maps to the name defined above in the workflow.json file.
  • When an entry point is named using any other string, it is prefixed with the name of the workflow, a slash, and the entry point name.

This means that in a workflow named "example" with the entry points "*" and "second" defined, example and example/second will be available.

Entry points are lua source files that include the functions defined below.

The init function.

This is the first function called after the file is loaded when running the workflow.

---@param workflow imgscal_WorkflowInit
function init(workflow)

end

Here the workflow argument is of type struct<imgscal.WorkflowInit>.

This is where built-in libraries must be imported, for example the init function from the resize entry point:

---@param workflow imgscal_WorkflowInit
function init(workflow)
    workflow.import({
        "cli",
        "filter",
        "io",
        "image",
    })
end
The main function.

This is called after the init function is finished. This is where the actual workflow code should begin, as built-in libraries are not available as globals until they are imported in the init function.

function main()

end

When importing other lua files as modules, the require function should also be called here.

The help function.

This is an optional function used when calling the help command for the workflow. This can only be used in entry points that are added to "cli_workflows" in workflow.json.

---@param workflow imgscal_WorkflowInfo
function help(info)
    return ""
end

Here the info argument is of type struct<imgscal.WorkflowInfo>.

This function must also return a string, this will be what the help command displays to the console.

Lua Modules

Lua files that are not entry points can be loaded as modules within the main function. There are two locations that are used by the lua module loader: the working directory of the workflow, and then the plugin directory defined in the config file.

example/
├── entrypoint.lua
├── mymodule.lua
└── workflow.json

In this example, entrypoint.lua can load mymodule.lua as a module with following code:
local mymodule = require("mymodule")

Inside of mymodule.lua there should be a table returned from the global scope.

The gui example contains a module widget.lua that is loaded by both filter.lua and noise.lua.

When loading a module from the plugin directory, it will also check for a path in a directory of the same name as the module.
So local mymodule = require("mymodule") would check in both:

  • plugin/mymodule.lua
  • plugin/mymodule/mymodule.lua

Built-in Commands

imgscal help <workflow>

Prints out the returned string from the workflow's help function.


The name "help" is reserved for this command, CLI entry points cannot be mapped to this name. Additionally, only CLI entry points can be called with this, and entry points missing the help function will panic.


imgscal list

Lists all available workflows and their entry points.


The name "list" is reserved for this command, CLI entry points cannot be mapped to this name.

Config File
{
    "$schema": "https://gist.githubusercontent.com/ArtificialLegacy/bf37b79d4fc943006f333cc35467266c/raw/933fdffd6d871d3bf5a281a7815b7d408fcd51b2/imgscal_config.json",
    "config_version": "",
    "config_directory": "%HOME%/imgscal/config",
    "workflow_directory": "%HOME%/imgscal/workflow",
    "output_directory": "%HOME%/imgscal/output",
    "input_directory": "%HOME%/imgscal/input",
    "log_directory": "%HOME%/imgscal/log",
    "plugin_directory": "%HOME%/imgscal/plugin",
    "default_author": "",
    "disable_logs": false,
    "always_confirm": false,
    "disable_bell": false
}

The config file is located at %CONFIG%/imgscal/config.json.

%CONFIG% is retrieved from os.UserConfigDir() and %HOME% from os.UserHomeDir() .


  • config_version - This is set based on a constant when created, currently unused but should not be changed. Will be used for compatibility if ever needed.
  • config_directory - This is the directory for loading workflow specific config and secret files.
    • Workflow configs are loaded from *.json files.
    • Workflow secrets are loaded from *.secrets.json files.
    • This directory includes a .gitignore file for **/*.secrets.json.
  • workflow_directory - This is the directory the program uses for finding and running workflows.
  • output_directory - This is a directory that can be used by workflows for outputting files. Each workflow with automatically get it's own directory.
    • Requires calling workflow.use_default_output() within the init function.
    • Workflows can get this directory with io.default_output().
  • input_directory - This is a directory that can be used by workflows for inputting files. Each workflow with automatically get it's own directory.
    • Requires calling workflow.use_default_input() within the init function.
    • Workflows can get this directory with io.default_input().
  • log_directory - This is the directory used to save log files from both the confirmation and execution stages of workflows.
    • The most recently generated log also gets saved as @latest.txt.
  • plugin_directory - This directory is used as a secondary path when calling require().
  • disable_logs - When this is set to true, it will disable all log output to files.
  • always_confirm - When this is set to true, the confirmation menu will be skipped before running a workflow.
  • disable_bell - Disables both cli.bell() and the workflow finish bell.
  • default_author - This value will be autofilled in the author section when using the imgscal-new tool.
Tools
These tools will require ImgScal to have been run at least once before using.
imgscal-new
Usage

imgscal-new
Installation

go install ./cmd/imgscal-new
Additonal Info

  • default_author in the config file will change the autofilled value for the author.
imgscal-entrypoint
Usage

imgscal-entrypoint <name> <path> [-c] [-w]
  • <name> - The name of the entry point, use "*" to bind to workflow name.
  • <path> - The path including the .lua file to create as the entry point. Any subdirectories included will be created if needed.
  • [-c] - Optional flag to create a cli entry point.
  • [-w] - Optional flag to to set the relative path to search for the workflow.json file.
Installation

go install ./cmd/imgscal-entrypoint
imgscal-log
Usage

imgscal-log
Installation

go install ./cmd/imgscal-log
imgscal-workspace
Usage

imgscal-workspace
Installation

go install ./cmd/imgscal-workspace
Log Files

There is an entrypoint at ./cmd/log that can be called to print the log file @latest.txt if it exists. make log is a shortcut for calling this.


The output of this can then be piped into other commads:

make log | grep '! ERROR'
make log | kate -i
make log > latest.txt
Log Prefixes

These are prepended at the start of each log line, use them to filter for specific events.

  • # SYSTEM
  • # INFO
  • ? WARN
  • ! ERROR
  • !! IMPORTANT
Type Information

When viewing the API documentation type inforamation will appear as: int. While lua does not have an int type, the documentation uses it to specify when a number value must be whole.


Types that begin with [] specify that it is a lua table with integer indexes starting at 1, in Go these indexes become 0 based.


Variadic arguments are specified with the suffix ..., these arguments will capture all remaining values on the stack in an array. Variadics can be both optional and required, when required at least one value must be present.


Optional Values

When a type is followed by a ? it means the value is optional. When an optional value is not provided, the zero value for that type will be used.

List of zero values:
Type Zero Value
int | float 0
string ""
bool false
table<any> {}
struct<Structure> {...Structure}
[]any | any... {} Numeric
function | any nil

Constraints

Sometimes a type may include two different types such as: int<collection.IMAGE>.

  • int is the type that exists within lua.
  • collection.IMAGE is the constraint on that type.
Here the value must be an int and be a valid id from collection.IMAGE.


Structs and Tables

There is also an additional special type called struct, this refers to a lua table with a specified structure. The constraint on these shows where that structure is defined in the documentation. E.g. struct<gui.Widget> is a struct named Widget defined in the gui library. When there is no specified structure, table<any> is used.

Environment Variables
IMGSCAL_CONFIG
This environment variable can be used to specify an alternative config file to use. The tool imgscal, will also create this file if it does not exist.

The following tools can make use of this:

  • imgscal
  • imgscal-new
  • imgscal-log

Structs


WorkflowInit

Properties

  • is_cli bool
Methods

debug

debug()


Open the lua debug library to the workflow.

verbose

verbose()


Enable verbose logging when running the workflow.

import

import([]string<imgscal_Imports>)


Array containing the import names for built-in libraries.

config

config(table<any>)


Set the default configuration for the workflow.

secrets

secrets(table<any>)


Set the default secrets for the workflow.

finish_bell

finish_bell()


Causes the bell control character to be printed when the workflow either finishes or fails.

use_default_input

use_default_input()


Enable using io.default_input().

use_default_output

use_default_output()


Enable using io.default_output().

WorkflowInfo

Properties

  • is_cli bool
  • name string
  • author string
  • version string
  • desc string