Difference between pages "LuaAPI/gui" and "ImagePathFunctions"

From The Battle for Wesnoth Wiki
< LuaAPI(Difference between pages)
(gui.show_prompt: Add documentation for gui.show_recruit_dialog and gui.show_recall_dialog)
 
(PAD: Pad function)
 
Line 1: Line 1:
{{DevFeature1.15|0}}
+
Image Path Functions provide a simple method for WML coders to alter the way their specified images will be displayed in the game. All of the function parameters are included at the end of an image path and should not contain any spaces or special characters (other than those specified here).
  
== Submodules ==
+
If you need to practice it without having to reload all WML, you can use an add-on named ''Image loading tester''.  It is available on the 1.9, 1.10, 1.11, 1.12 and 1.14 add-on servers.
=== gui.widget ===
 
  
A [[LuaAPI/gui/widget|submodule]] containing functions for working with widgets in custom dialogs.
+
All functions are applied in left-to-right order, with the exception of RC(), TC() and PAL() which are applied always before any other functions. Standard team coloring for a unit is applied after all custom RC(), TC() and PAL() functions but before any other functions.
 +
That is, stuff like
 +
"units/elves-wood/fighter.png~CROP(20,20,40,40)~CROP(10,10,10,10)"
 +
would result in taking a crop to a 40x40 rectangle whose top-left corner is x=20, y=20; and then taking a crop from ''that'' rectangle with x=10, y=10, w=10, h=10. The result is the area x=30, y=30, w=10, h=10 from the original graphic.
  
== Functions ==
+
== Changing the colors ==
=== gui.add_widget_definition ===
 
  
* '''gui.add_widget_definition'''(''widget_type'', ''definition_id'', ''wml_content'')
+
=== BLEND: Color-blend function ===
 +
Blends the image with the given color to produce a more controlled tinting effect than color-shifting, independently of the image's contents.
  
Creates a new WML widget definition for the specified widget type, which can be referenced from dialog WML in the '''definition''' key.
+
'''~BLEND(r,g,b,o)'''
  
=== gui.get_user_choice ===
+
The color is defined by the ''r'', ''g'', and ''b'' parameters (integers ranging from 0 to 255). The ''o'' (opacity) parameter controls the amount by which the given color will be blended into the image, and may be specified either as a factor from 0.0 to 1.0, or percentage up to 100%. Thus, ~BLEND(r,g,b,0.5) and ~BLEND(r,g,b,50%) are equivalent.
  
* '''gui.get_user_choice'''(''attributes'', ''options'')
+
=== BW: Black and White function ===
 +
{{devfeature1.13|1}}
 +
May be used to convert the image to pure black and white, without grey pixels.
  
Shows a message dialog (like the one used by the <tt>[[InterfaceActionsWML#.5Bmessage.5D|[message]]]</tt> tag) with a series of options and returns the index (1-based) of the chosen option, which can be stored as a Lua variable.
+
'''~BW(threshold)'''
 +
* ''threshold'': a value between 0 and 255 (both limits included). All pixels are converted as greyscale first, and if their average value is greater than the threshold they become white, otherwise they become black.
  
'''IMPORTANT NOTE: this function is broken in Wesnoth 1.16.0 and 1.16.1.''' If you wish to use it, you should also use wesnoth.current_version to check that your code is being run on Wesnoth 1.16.2 or higher. Alternatively, you may try using [[#gui.show_narration|gui.show_narration]] instead, which has a similar function but a wider range of features.
+
=== CS: Color-shift function ===
 +
Performs simple per-channel color shifts by adding the arguments to the respective color channels.
  
The first argument is a table of attributes which are directly passed to the underlying <tt>[message]</tt> tag.
+
''Multi-channel:'' '''~CS(r,g,b)'''
 +
''Single-channel:'' '''~R(v)''', '''~G(v)''', '''~B(v)'''
  
The second argument is a table of options, which are used to construct a series of underlying <tt>[option]</tt> tags. Most Lua data types are supported, but a few aren't:
+
The multichannel syntax assumes all arguments are set to zero initially, so one can use, e.g. ~CS(2,4) to add +2 and +4 units to the red and green channels respectively, leaving the blue channel intact. Arguments may be negative to diminish a channel's value; this can be used to change an image's brightness. Checks for out-of-range arguments or results (less than 0 or greater than 255) are made, so the resultant values are truncated if necessary.
* If the option is a ''table'' or a ''WML table'', these fields are supported:
 
** ''image'': icon shown in the first column;
 
** ''label'': text shown in the second column;
 
** ''description'': text shown in the third column (''message'' is also supported as an alias);
 
** ''default'': whether this is option is the one selected when the dialog is shown (boolean).
 
* If the option can be cast to a string (''strings'', ''translatable strings'', ''numbers'', ''booleans''), it is used for the content of the description field, which means that the first two columns will be empty.
 
* Otherwise, it raises an "invalid data type" error.
 
  
Example taken from the test scenario (if not used in an event then change the speaker):
+
The single channel syntax behaves exactly the same, except that only single-channel modifications are made per function. However, one can stack them to produce the same behavior as ~CS(), e.g. ~R(r)~G(g)~B(b), but that tends to be just a performance loss.
  
<syntaxhighlight lang='lua'>
+
=== GS: Greyscale function ===
local result = gui.get_user_choice(
+
May be used to greyscale the image (turn to black and white)
    { speaker = "unit", message = "Pick your poison" },
 
    { { image = "items/potion-red.png",
 
        label = "Something red",
 
        description = "Take a sip and enjoy" },
 
      { image = "items/potion-blue.png",
 
        label = "Nice blue",
 
        description = "Surely you’ll like that one",
 
        default = true },
 
      { image = "items/potion-yellow.png",
 
        label = "<span color='yellow'>Oh noes yellow</span>",
 
        description = "Oh I’m sure you’ll love that one" },
 
      { image = "scenery/well.png",
 
        label = "A nice well",
 
        description = "Grab a bucket and fetch some water" },
 
      { image = "items/holy-water.png",
 
        label = "Oh nice bottle",
 
        description = "Feel the divinity" },
 
      -- Should have an empty first column and a second column on two lines.
 
      { label = "Well a nice and black drink.\nToo dark too see?",
 
        description = "Take a sip and pass the bottle along" }
 
    })
 
wesnoth.interface.add_chat_message(string.format("User selected choice %d.", result))
 
</syntaxhighlight>
 
  
=== gui.show_dialog ===
+
'''~GS( )'''
  
* '''gui.show_dialog'''(''dialog definition'', ''preshow'', ''postshow'') &rarr; ''retval''
+
=== L: Lightmap color-shift function ===
 +
Performs per-pixel and per-channel color shifts using another image (a "lightmap") as source, allowing to create textured light effects.
  
Displays a dialog box described by a WML table and returns an integer
+
'''~L(lightmap)'''
* if the dialog was dismissed by a button click, the integer value associated to the button via the '''return_value''' keyword.
 
* if the dialog was closed with the enter key, -1.
 
* if the dialog was closed with the escape key, -2.
 
  
The dialog box is equivalent to the '''[resolution]''' section of a GUI window as described in [[GUIToolkitWML]] and must therefore contain at least the following children: '''[tooltip]''', '''[helptip]''', and '''[grid]'''. The [grid] must contain nested [row], [column] and [grid] tags which describe the layout of the window. (More information can be found in GUIToolkit page's [[GUIToolkit#Layout|Layout]] section and [[GUILayout]]; suffice to say that the basic structure is grid -> row -> column -> widget, where the widget is considered to be in a cell defined by the row and column of the grid. A list of widgets can be found at [[GUIWidgetInstanceWML]].) For an overview of the GUI system, see [[GUIToolkit]].
+
For each pixel of the original image, it checks the RGB values from the corresponding pixel of the lightmap, slightly transform them, then add these values to the original pixel.
  
Two optional functions can be passed as second and third arguments; the function passed as ''preshow'' argument is called just before the dialog is shown; the second function (argument ''postshow'') is called once the dialog is closed. These functions are helpful in setting the initial values of the fields and in recovering the final user values. These functions take a single parameter, which is the [[LuaAPI/types/widget|widget userdata]] representing the window.
+
The transformation involved is done to convert the (0,255) spectrum to (-255,255), allowing to add or subtract color. The formula is (x-128)*2, which means that 0 gives -256, 128 gives 0 and 255 gives 254. So, the no-effect lightmap is a fully grey image (RGB = 128,128,128) and any non-grey pixel will shift the colors of the original.
  
For in-game dialogs that offer the player a choice and/or can change the game state, this function should be called in conjunction with [[LuaAPI/wesnoth/sync#evaluate_single|wesnoth.sync.evaluate_single]], in order to ensure that only one client displays the dialog and that the other ones recover the same input values from this single client. Though this is especially important in multiplayer scenarios, failing to do it in a single-player scenario will cause the replay to break, so it should be done in either case.
+
Note that the lightmap will be scaled to the same dimensions as the original image.
  
See [[LuaAPI/gui/example|here]] for a fully-working example of a custom dialog.
+
=== NEG: Negative function ===
 +
{{devfeature1.13|0}}
 +
Also known as ''invert'', it negates all the RGB values of the image, giving it an effect similar to a photographic negative.
  
=== gui.show_help ===
+
'''~NEG( )'''
  
* '''gui.show_help'''([''topic''])
+
Inverts the image, giving it an effect like a photographic negative.
  
Show the in-game help, optionally opening a specified topic directly.
+
{{devfeature1.13|1}} '''~NEG(''' ''threshold'' ''')'''
  
=== gui.show_inspector ===
+
If a channel has a value greater than the threshold, the channel will be inverted, performing an effect known as ''solarization''.
 +
Threshold must be between -1 and 255, with -1 equivalent to full inversion and 255 as no-op value.
  
* {{LuaGameOnly}} '''gui.show_inspector'''()
+
{{devfeature1.13|1}} '''~NEG(''' ''threshold_red, threshold_green, threshold_blue'' ''')'''
  
Show the gamestate inspector.
+
If a channel has a value greater than the corresponding threshold, the channel will be inverted.
 +
Each threshold must be between -1 and 255, with -1 equivalent to full inversion and 255 as no-op value.
  
=== gui.show_lua_console ===
+
=== PAL: Palette-switch function ===
 +
May be used to change colors in an image following the specifications of a source and target (new) palette.
  
* '''gui.show_lua_console'''()
+
'''~PAL(''' ''source color palette'' '''>''' ''target color palette'' ''')'''
 +
*''source color palette'' - the first parameter is a source color palette, such as magenta. Do not surround this parameter with quotes.
 +
*''target color palette'' - the new palette to take the place of the source colors in the image.
  
Shows the Lua console. This works even if debug mode is not enabled.
+
A color palette can be either the attribute name from '''[[GameConfigWML#Color_Palettes|[color_palette]]]''' (like magenta) or a comma separated list of hex color values.
  
 +
=== RC: Re-Color function ===
 +
May be used to change some colors in an image. It is possible to use ''RC'' more than once on the same image, with different source palettes.
  
=== gui.show_menu ===
+
'''~RC(''' ''source color palette'' '''>''' ''destination color range'' ''')'''
  
* '''gui.show_menu'''(''items'', [''initial''], [''markup'']) &rarr; ''index''
+
==== source color palette ====
 +
The first parameter is a set of colors, usually the magenta palette. Do not surround this parameter with quotes. The three standard palettes are:
  
Shows a popup menu onscreen at the current mouse location. This could be used for example to produce a sort of submenu in a <tt>[set_menu_item]</tt>. The items are specified as a Lua array of tables, each of which supports the following keys:
+
* '''magenta''' - the 19 colors described in [[Team_Color_Shifting]]
 +
* '''ellipse_red''' - all 255 colors with RGB value (n,0,0)
 +
* '''flag_green''' - all 255 colors with RGB value (0,n,0)
  
* ''icon'': An icon to display in the leftmost column of the menu.
+
The palette can also be given inline as a set of hexadecimal RGB values.
* ''image'': An image to display in the main column of the menu. If this is present, ''label'' is ignored.
 
* ''label'': A label to display in the main column of the menu.
 
* ''details'': A secondary label to display in the right column of the menu.
 
* ''tooltip'': Text to display when mousing over this option.
 
  
The ''initial'' argument must be a valid index into the ''items'' array, or 0 to indicate that no element is initially selected (which is the default but typically not what you want).
+
The named palettes are defined using the '''[[GameConfigWML#Color_Palettes|[color_palette]]]''' tag, and you can also define your own custom color palette using that tag.
  
The ''markup'' argument specifies whether Pango markup will be parsed in the menuitems. It defaults to false.
+
Warning: the RC function will also accept (and not give a warning about) '''red''', '''green''' and any other defined '''[color_range]'''; however the set of RGB values for those aren't guaranteed. Using '''red''' instead of '''ellipse_red''' might be equivalent to the palette 030000,060000,0a0000,...,ff0000,ff0a0a,...,fff0f0.
  
The ''initial'' and ''markup'' arguments can be passed in either order; the game will understand which is meant based on the type of the argument.
+
==== destination color range ====
 +
This is the second parameter, signifying the ID of a color range defined in the file [http://github.com/wesnoth/wesnoth/blob/master/data/core/team-colors.cfg data/core/team-colors.cfg] (or it may be a custom ID for a color range defined locally). You can also define a custom color range inline (the rgb key from [[GameConfigWML#Color_Palettes]]; note that RC does not use the fourth color for anything).
  
This function returns the index of the selected item. If the user cancelled by clicking outside the menu's boundary, 0 is returned.
+
For this destination color range, using '''red''' or '''green''' makes sense.
  
=== gui.show_narration ===
+
==== Example ====
 +
In the following example, the magenta regions in an elvish captain's image are turned a healthy shade of green:
  
* '''gui.show_narration'''(''attributes'', [''options'', [''text_input_attributes'']]) &rarr; ''result_code'', [''entered_text'']
+
  [message]
 +
      speaker=narrator
 +
      image=units/elves-wood/captain.png~RC(magenta>green)
 +
      message=_ "Now I am on the green team."
 +
  [/message]
  
Shows a message dialog, of the type used by the <tt>[message]</tt> ActionWML tag. Unlike the <tt>[message]</tt> tag, this is unsynced; if you need it synced, you must do it yourself. The first argument is a table describing the dialog with the following keys:
+
The following example replaces a few of the '''magenta''' pixels with green ones:
  
* ''title'' - The title to show on the message. For example, the speaker's name.
+
  misc/orb.png~RC(690039,c30074,ec008c > 007f00,00ff00,000000,000000)
* ''message'' - The message content.
 
* ''portrait'' - An image to show along with the message. By default, no image is shown.
 
* ''left_side'' - The default is true; set to false to show the image on the right.
 
* ''mirror'' - If true, the image will be flipped horizontally.
 
  
The second argument is a list of options as a Lua array. Each option is either a (possibly-translatable) string or a config with [[DescriptionWML#WML_Format|DescriptionWML]] keys. The array itself can also have an optional '''default''' key which if present should be the index of the initially selected option (useful if you don't need full DescriptionWML but want to set a default). If present it overrides any defaults set in individual options.
+
The IDs of the color ranges may be the lowercased English name of the palette's base color (e.g. 'red', 'brown', etc.). They may also be numeric color indices from the palette WML included with the game, but this is not recommended.
  
The third argument is a table describing the text input field with the following keys:
+
=== SEPIA: Sepia function ===
 +
{{devfeature1.13|0}}
 +
May be used to give to the image a sepia tint (like in old pictures).
  
* ''label'' - A label to show to the left of the text field.
+
'''~SEPIA()'''
* ''text'' - Initial contents of the text field.
 
* ''max_length'' - Maximum input length in characters (defaults to 256).
 
  
You need at least one key for the text input to be shown. Both the second and third arguments are optional, but if you want text input with no options, you must pass nil for the second parameter.
+
=== SWAP: Channel Swap function ===
 +
{{devfeature1.13|1}}
 +
May be used to swap the RGBA channels of an image.
  
This function returns one or two values. The first value returned is the numeric result of the dialog:
+
'''~SWAP(''' ''r, g, b'' ''')'''
 +
'''~SWAP(''' ''r, g, b, a'' ''')'''
 +
* ''r'', ''g'', ''b'', ''a'': each of these arguments may have a value equal to ''red'', ''green'', ''blue'' or ''alpha''. The RGBA channels of the original image will be exchanged accordingly (for example, <tt>~SWAP(blue,green,red)</tt> swaps the blue and red channels).
  
* If there are no options and no text input, the result is -2 if the user pressed Escape, or -1 if they closed by clicking or pressing Space.
+
=== TC: Team-Color function ===
* If there are options, the result is the index of the option chosen (starting from 1).
+
In Wesnoth version 1.2, the only Image Path Function was '''~TC()''', which took two comma-separated parameters: the team number and the source color palette. The valid values for both of these parameters are defined in the file ''data/team-colors.cfg''
* If there is text input but no options, the first return value is 0.
 
  
The second value returned is the text entered, if there was text input. Otherwise there is no second value (it is nil).
+
'''~TC(''' ''team number'' ''',''' ''source color palette'' ''')'''
 +
*''team number'' - this is the first parameter, a number 1-9 signifying the team number of a unit. Number 1 typically means the red team, 2 typically means the blue team, and so on (unless the scenario color settings for any side have been altered).
 +
*''source color palette'' - the second parameter is a source color palette, usually magenta. Do not surround this parameter with quotes.
  
Example:
+
== Transformations ==
  
<syntaxhighlight lang='lua'>
+
=== FL: Flip function ===
gui.show_narration({
+
May be used to flip an image horizontally and/or vertically.
    title = "Make your choice:",
 
    message = "Select an option and enter some text.",
 
    portrait = "wesnoth-icon.png",
 
}, {
 
    "The first choice is always the best!",
 
    "Pick me! Second choices are better!",
 
    "You know you want the third option!",
 
}, {
 
    label = "Text:",
 
    text = "?",
 
    max_length = 16
 
})
 
</syntaxhighlight>
 
  
(You don't have to format it like that, of course.)
+
'''~FL(''' ''optional argument list'' ''')'''
 +
*''vertical'' - if the string "vert" is found anywhere in the argument list, the image will be flipped vertically.
 +
*''horizontal'' - if the string "horiz" is found anywhere in the argument list, the image will be flipped horizontally.
 +
*if the argument list is empty, the image will only be flipped horizontally.
  
=== gui.show_popup ===
+
=== ROTATE: Rotate function ===
 +
May be used to rotate an image.
  
* '''gui.show_popup'''(''title'', ''message'', [''image''])
+
'''~ROTATE(''' ''degrees'' ''')'''
 +
* ''degrees'' - The number of degrees by which the image will be rotated. Positive numbers indicate clockwise rotation, while negative numbers indicate counter-clockwise. (Zero indicates no rotation.)
 +
If the number of degrees is omitted, a quarter turn (90 degrees) clockwise is assumed.
  
Shows a simple popup dialog in the centre of the screen. Takes three arguments, which in order are:
+
=== SCALE: Image-scaling function ===
 +
Scales a graphic up or down.
  
# A title string for the dialog
+
'''~SCALE( ''new_width'', ''new_height'' )
# The message content for the dialog.
 
# An image to show.
 
  
Both the title and the message support Pango markup. The image is optional.
+
The ''new_width'' and ''new_height'' parameters are taken as the image's original width or height, respectively, if one of them happens to be zero. Negative values are treated in the same way, but an error is printed in stderr. This uses the bilinear interpolation algorithm.
  
=== gui.show_prompt ===
+
=== SCALE_INTO function ===
 +
{{DevFeature1.13|5}}
  
* '''gui.show_prompt'''(''title'', ''message'', [''button''], [''markup'']) &rarr; ''result''
+
Similar to SCALE, but preserves aspect aspect ratio, scaling to the minimum extent required to fit into the specified area. The resulting image will have the specified width or the specified height, but not necessarily both.
* '''gui.confirm'''([''title'',] ''message'') &rarr; ''result''
 
* '''gui.alert'''([''title''], ''message'')
 
  
Shows a standard message box onscreen (similar to the quit confirmation message, for example). The button can be any arbitrary potentially-translatable string (in which case, there will be one button with that label), or it can be one of the following special string values:
+
=== SCALE_SHARP function ===
  
* ''ok'' or nil: A single OK button; this is the default
+
{{DevFeature1.13|0}}
* ''cancel'': A single Cancel button
 
* ''close'': A single Close button
 
* ''ok_cancel'': Two buttons labelled OK and Cancel
 
* ''yes_no'': Two buttons labelled Yes and No
 
* an empty string: No buttons; the dialog automatically closes after a few seconds
 
  
The alert and confirm functions are simpler wrappers for this function, using a single OK button and a pair of Yes/No buttons, respectively. Both confirm and show_prompt return false if No or Cancel was clicked, and true otherwise. The alert function returns nothing.
+
Scales functions using a nearest neighbor algorithm. Specify width and height. (It has the same syntax as ~SCALE.)
  
=== gui.show_recruit_dialog ===
+
'''~SCALE_SHARP(200,300)'''
  
* '''gui.show_recruit_dialog'''(''unit_types_list'', [''unit_dialog_options''])
+
=== SCALE_INTO_SHARP function ===
 +
{{DevFeature1.13|5}}
  
The first argument is a table of [[LuaAPI/types#Unit_Type|unit types]]. The second argument is an optional table that can be used to set various properties of the dialog shown. These are:
+
Like SCALE_INTO, but uses nearest neighbor algorithm instead of bilinear interpolation.
  
* '''title''': the title of the dialog.
+
=== XBRZ function ===
* '''ok_label''': caption of the button with id "ok".
 
* '''cancel_label''': caption of the button with id "cancel".
 
* '''help_topic''': the help topic that is to be opened when the '?' button is clicked.
 
* '''show_headers''': (boolean) whether to show column headers in the main list of the dialog. By default, the headers are not shown.
 
  
=== gui.show_recall_dialog ===
+
{{DevFeature1.13|0}}
  
* '''gui.show_recall_dialog'''(''units_list'', [''unit_dialog_options''])
+
Scales functions using the XBRZ algorithm. You may scale things up either 2x, 3x, 4x, or 5x. The scaling tries to preserve the pixel art nature.
  
The first argument is a table of [[LuaAPI/types/unit|units]]. The second argument is an optional table that can be used to set various properties of the dialog shown. These are:
+
'''~XBRZ(n)'''
  
* '''title''': the title of the dialog.
+
== Cut-paste-extend ==
* '''ok_label''': caption of the button with id "ok".
 
* '''cancel_label''': caption of the button with id "cancel".
 
* '''help_topic''': the help topic that is to be opened when the '?' button is clicked.
 
* '''show_headers''': (boolean) whether to show column headers in the main list of the dialog. By default, the headers are shown.
 
  
=== gui.show_story ===
+
=== BLIT: Blit function ===
 +
Blit (superimpose) the parameter image on the main image. Example: peasant.png~BLIT(hat.png,30,10)
  
* '''gui.show_story'''(''story_config'', ''default_title'')
+
'''~BLIT(src,x,y)'''
 +
* ''src'': an image file used as source for the blit, other image path functions can be used there.
 +
* ''x'',''y'': top-left corner coordinates where to blit. If missing assume (0,0).
  
Shows the storyscreen. The passed config is identical to the contents of [[IntroWML|[story]]]. The second parameter is the default title used if a part does not specify one — unlike intro storyscreens, a Lua-invoked one does not default to the scenario name.
+
=== CROP: Crop function ===
 +
Extracts a rectangular section of an image file.
  
=== gui.switch_theme ===
+
'''~CROP(x,y,width,height)'''
 +
* ''x'',''y'': top-left corner coordinates for the rectangular section extracted. Must be greater or equal than zero, and inside the image's bounds.
 +
* ''width'': width of the selected region. Must be less than or equal to the original image's width, and must not be negative.
 +
* ''height'': height of the selected region. Must be less than or equal to the original image's height, and must not be negative.
  
* '''gui.switch_theme'''(''theme_id'')
+
=== CROP_TRANSPARENCY ===
 +
{{devfeature1.17|26}}
 +
Removes any transparent padding from around an image.
  
Switch to the GUI2 theme with id ''theme_id''. Can only be used inside a scenario and does not replace the UI Theme selected by Preferences. The UI reverts to the theme selected in Preferences after exiting the in-game window, for example, by using the menu or by winning or losing a campaign.
+
'''~CROP_TRANSPARENCY()'''
  
[[Category:Lua Reference]]
+
=== PAD: Pad function===
 +
{{devfeature1.19|17}}
 +
Extends side(s) of an image with transparent pixels.
 +
 
 +
'''~PAD(..)'''
 +
*called with a single number like ''~PAD(10)'' and it will add a 10 pixel padding to every side.
 +
*called with keys (top, t, right, r, bottom, b, left, l) like ''~PAD(bottom=10, t=5)'' and it will pad those sides by that much.
 +
Can be used to create a fake offset by padding one side of an image in order to push it in the opposite direction.
 +
 
 +
=== MASK: Mask function ===
 +
Remove parts of the main image using the parameter image as a mask. Example: grass.png~MASK(circle.png) will give a circle of grass.
 +
 
 +
'''~MASK(mask,x,y)'''
 +
* ''mask'': an image file used as mask, other image path functions can be used there.
 +
* ''x'',''y'': top-left corner coordinates where to put the mask. Parts ouside of the mask are considered transparent. If missing assume (0,0).
 +
 
 +
Only the alpha channel of the mask is used and each alpha value will be the maximum alpha of the resulting image. This means that the fully-transparent parts of the mask will erase the corresponding parts of the image, but also that a semi-transparent mask will create a semi-transparent image.
 +
 
 +
== Opacity ==
 +
 
 +
=== ADJUST_ALPHA ===
 +
 
 +
{{DevFeature1.13|?}}
 +
 
 +
Alters the alpha of the image according to a WFL formula. The formula must output an integer from 0 to 255 giving the alpha across the canvas. It is evaluated for every pixel and may use the following variables: x, y, red, green, blue, alpha, width, height. {{DevFeature1.15|0}} The variables u and v are also supported now, evaluating to normalized texture coordinates (in the range 0..1); these are equivalent to <tt>x/width</tt> and <tt>y/height</tt> respectively.
 +
 
 +
'''~ADJUST_ALPHA(formula)'''.
 +
 
 +
The context object for the formula is a '''[[#CHAN:_General_function|pixel object]]'''.
 +
 
 +
=== O: Opacity modifying function ===
 +
Changes an image's opacity at render time.
 +
 
 +
'''~O( ''factor or percentage%'' )'''
 +
 
 +
If the argument includes the percentage symbol (''%''), it will be treated as a percentage of full (real) opacity; an image will be displayed at its native opacity with ~O(100%).
 +
 
 +
Without the percentage symbol, the argument is assumed to be a factor by which the image's native opacity should be multiplied. Thus, ~O(0.5) and ~O(50%) are equivalent forms of specifying to reduce an image's opacity by half.
 +
 
 +
=== PLOT_ALPHA ===
 +
 
 +
{{DevFeature1.13|0}}
 +
 
 +
At each pixel, the color is replaced with a grey-tone reflecting the alpha value at that pixel, and the new image is fully opaque. Useful for plotting the alpha to help debug an IPF or inspect a sprite.
 +
 
 +
'''~PLOT_ALPHA()'''
 +
 
 +
=== WIPE_ALPHA ===
 +
 
 +
{{DevFeature1.13|0}}
 +
 
 +
At each pixel, the alpha value is discarded and the pixel is made fully opaque. Useful again for diagnostics.
 +
 
 +
'''~WIPE_ALPHA()'''
 +
 
 +
=== Background coloring function ===
 +
Sets the color of all the (semi-)transparent pixels of the image.
 +
 
 +
'''~BG(r,g,b)'''
 +
 
 +
== Miscellaneous ==
 +
 
 +
=== BL: Blurring function ===
 +
 
 +
Blurs a graphic at render time using the same algorithm used for in-game dialogs.
 +
 
 +
'''~BL( ''radius'' )'''
 +
 
 +
=== CHAN: General function ===
 +
 
 +
{{DevFeature1.13|7}}
 +
 
 +
This function allows you to do pretty much anything. It takes up to four comma-separated formulas, one each for the red, green, blue, and alpha channels. Each formula functions exactly the same as the formula for '''ADJUST_ALPHA''', but the output integer is used for the corresponding channel rather than always the alpha channel. Do not surround the formula in <code>$(...)</code>, since that will erase the <tt>self</tt> variable.
 +
 
 +
'''~CHAN(formula, formula, formula)'''
 +
 
 +
The context object for each of the formulas is a '''pixel object''' with the following properties:
 +
 
 +
* '''x''', '''y''': coordinates of the pixel, from the top left
 +
* '''u''', '''v''': {{DevFeature1.15|0}} normalized coordinates in the range [0,1]
 +
* '''width''', '''height''': size of the image canvas
 +
* '''red''', '''green''', '''blue''', '''alpha''': components of the pixel colour
 +
 
 +
=== DARKEN: Removed function ===
 +
 
 +
{{DevFeature1.13|7}} This function has been removed. Use a ~BLIT(misc/tod-dark.png) call instead.
 +
 
 +
Puts a time-of-day schedule overlay (misc/tod-dark.png) on the image, which must be large enough to accommodate it.
 +
 
 +
'''~DARKEN()'''
 +
 
 +
=== BRIGHTEN: Removed function ===
 +
 
 +
{{DevFeature1.13|7}} This function has been removed. Use a ~BLIT(misc/tod-bright.png) call instead.
 +
 
 +
Puts a time-of-day schedule overlay (misc/tod-bright.png) on the image, which must be large enough to accommodate it.
 +
 
 +
'''~BRIGHTEN()'''
 +
 
 +
=== NOP: Null function ===
 +
 
 +
Does nothing.
 +
 
 +
'''~NOP()'''
 +
 
 +
=== Pseudo IPFs ===
 +
 
 +
The following functions are ignored by the IPF image modification module, but used by other Wesnoth components. They only work in special areas.
 +
 
 +
==== NO_TOD_SHIFT: Disabling ToD ====
 +
 
 +
{{DevFeature1.13|8}}
 +
 
 +
This is used by the terrain renderer and prevents terrain and item images from being affected by ToD lighting. This is in particular useful when placing unit images as items, as they will look the same as when placed as unit.
 +
 
 +
'''~NO_TOD_SHIFT()'''
 +
 
 +
==== RIGHT: Display portraits on the right ====
 +
 
 +
'''''([[DevFeature|Version 1.5.8 and later only]])'''''
 +
 
 +
This is used by the [[InterfaceActionsWML#.5Bmessage.5D|'''[message]''']] interface action and can be used to show a portrait on the right side of the screen.
 +
 
 +
'''~RIGHT()'''
 +
 
 +
== Creating an image file from IPFs ==
 +
 
 +
The big advantage of Image Path Functions is that they allow you to alter an image without needing a new image file. However, you can also save the result into a new image file using Wesnoth's command line option ''--render-image'.
 +
 
 +
Assuming you find a way to open your computer's terminal:
 +
wesnoth --render-image "units/human-peasants/ruffian.png~RC(magenta>green)~BLIT(units/human-peasants/woodsman.png~RC(magenta>lightblue),18,12)" /tmp/new_image_file.png
 +
 
 +
Or on Windows:
 +
"C:\Path\to\Battle for Wesnoth\wesnoth.exe" --render-image "units/human-peasants/ruffian.png~RC(magenta>green)~BLIT(units/human-peasants/woodsman.png~RC(magenta>lightblue),18,12)" new_image_file.png
 +
 
 +
Use cases include:
 +
* Experimenting with Image Path Functions. If none of the images are from an add-on, adding ''--noaddons'' will speed this up.
 +
* If a new Image Path Function is added to the development version of Wesnoth, add-ons for older Wesnoth versions can use a generated image instead.
 +
* In case you want to use this anywhere out of Wesnoth. On a website, in Project Haldric, …
 +
== See Also ==
 +
 
 +
* [[FancyAddonIcons]] - Tips and tricks for advanced Image Path Function manipulation
 +
* [[DataURI]] - An image path may also contain the image directly, as a Base64 encoded string
 +
* [https://irydacea.me/projects/wespal Wespal]  - Tool to preview unit recoloring. Covers the effects of the [[#RC:_Re-Color_Function|RC]], [[#TC: Team-Color Function|TC]] and [[#PAL:_Palette-switch_Function|PAL]] functions.
 +
* [https://github.com/wesnoth/wesnoth/blob/master/src/image_modifications.cpp src/image_modifications.cpp] - file where IPFs are implemented
 +
[[Category:WML Reference]]

Revision as of 17:24, 29 September 2025

Image Path Functions provide a simple method for WML coders to alter the way their specified images will be displayed in the game. All of the function parameters are included at the end of an image path and should not contain any spaces or special characters (other than those specified here).

If you need to practice it without having to reload all WML, you can use an add-on named Image loading tester. It is available on the 1.9, 1.10, 1.11, 1.12 and 1.14 add-on servers.

All functions are applied in left-to-right order, with the exception of RC(), TC() and PAL() which are applied always before any other functions. Standard team coloring for a unit is applied after all custom RC(), TC() and PAL() functions but before any other functions. That is, stuff like

"units/elves-wood/fighter.png~CROP(20,20,40,40)~CROP(10,10,10,10)"

would result in taking a crop to a 40x40 rectangle whose top-left corner is x=20, y=20; and then taking a crop from that rectangle with x=10, y=10, w=10, h=10. The result is the area x=30, y=30, w=10, h=10 from the original graphic.

Changing the colors

BLEND: Color-blend function

Blends the image with the given color to produce a more controlled tinting effect than color-shifting, independently of the image's contents.

~BLEND(r,g,b,o)

The color is defined by the r, g, and b parameters (integers ranging from 0 to 255). The o (opacity) parameter controls the amount by which the given color will be blended into the image, and may be specified either as a factor from 0.0 to 1.0, or percentage up to 100%. Thus, ~BLEND(r,g,b,0.5) and ~BLEND(r,g,b,50%) are equivalent.

BW: Black and White function

(Version 1.13.1 and later only) May be used to convert the image to pure black and white, without grey pixels.

~BW(threshold)

  • threshold: a value between 0 and 255 (both limits included). All pixels are converted as greyscale first, and if their average value is greater than the threshold they become white, otherwise they become black.

CS: Color-shift function

Performs simple per-channel color shifts by adding the arguments to the respective color channels.

Multi-channel: ~CS(r,g,b) Single-channel: ~R(v), ~G(v), ~B(v)

The multichannel syntax assumes all arguments are set to zero initially, so one can use, e.g. ~CS(2,4) to add +2 and +4 units to the red and green channels respectively, leaving the blue channel intact. Arguments may be negative to diminish a channel's value; this can be used to change an image's brightness. Checks for out-of-range arguments or results (less than 0 or greater than 255) are made, so the resultant values are truncated if necessary.

The single channel syntax behaves exactly the same, except that only single-channel modifications are made per function. However, one can stack them to produce the same behavior as ~CS(), e.g. ~R(r)~G(g)~B(b), but that tends to be just a performance loss.

GS: Greyscale function

May be used to greyscale the image (turn to black and white)

~GS( )

L: Lightmap color-shift function

Performs per-pixel and per-channel color shifts using another image (a "lightmap") as source, allowing to create textured light effects.

~L(lightmap)

For each pixel of the original image, it checks the RGB values from the corresponding pixel of the lightmap, slightly transform them, then add these values to the original pixel.

The transformation involved is done to convert the (0,255) spectrum to (-255,255), allowing to add or subtract color. The formula is (x-128)*2, which means that 0 gives -256, 128 gives 0 and 255 gives 254. So, the no-effect lightmap is a fully grey image (RGB = 128,128,128) and any non-grey pixel will shift the colors of the original.

Note that the lightmap will be scaled to the same dimensions as the original image.

NEG: Negative function

(Version 1.13.0 and later only) Also known as invert, it negates all the RGB values of the image, giving it an effect similar to a photographic negative.

~NEG( )

Inverts the image, giving it an effect like a photographic negative.

(Version 1.13.1 and later only) ~NEG( threshold )

If a channel has a value greater than the threshold, the channel will be inverted, performing an effect known as solarization. Threshold must be between -1 and 255, with -1 equivalent to full inversion and 255 as no-op value.

(Version 1.13.1 and later only) ~NEG( threshold_red, threshold_green, threshold_blue )

If a channel has a value greater than the corresponding threshold, the channel will be inverted. Each threshold must be between -1 and 255, with -1 equivalent to full inversion and 255 as no-op value.

PAL: Palette-switch function

May be used to change colors in an image following the specifications of a source and target (new) palette.

~PAL( source color palette > target color palette )

  • source color palette - the first parameter is a source color palette, such as magenta. Do not surround this parameter with quotes.
  • target color palette - the new palette to take the place of the source colors in the image.

A color palette can be either the attribute name from [color_palette] (like magenta) or a comma separated list of hex color values.

RC: Re-Color function

May be used to change some colors in an image. It is possible to use RC more than once on the same image, with different source palettes.

~RC( source color palette > destination color range )

source color palette

The first parameter is a set of colors, usually the magenta palette. Do not surround this parameter with quotes. The three standard palettes are:

  • magenta - the 19 colors described in Team_Color_Shifting
  • ellipse_red - all 255 colors with RGB value (n,0,0)
  • flag_green - all 255 colors with RGB value (0,n,0)

The palette can also be given inline as a set of hexadecimal RGB values.

The named palettes are defined using the [color_palette] tag, and you can also define your own custom color palette using that tag.

Warning: the RC function will also accept (and not give a warning about) red, green and any other defined [color_range]; however the set of RGB values for those aren't guaranteed. Using red instead of ellipse_red might be equivalent to the palette 030000,060000,0a0000,...,ff0000,ff0a0a,...,fff0f0.

destination color range

This is the second parameter, signifying the ID of a color range defined in the file data/core/team-colors.cfg (or it may be a custom ID for a color range defined locally). You can also define a custom color range inline (the rgb key from GameConfigWML#Color_Palettes; note that RC does not use the fourth color for anything).

For this destination color range, using red or green makes sense.

Example

In the following example, the magenta regions in an elvish captain's image are turned a healthy shade of green:

 [message]
     speaker=narrator
     image=units/elves-wood/captain.png~RC(magenta>green)
     message=_ "Now I am on the green team."
 [/message]

The following example replaces a few of the magenta pixels with green ones:

 misc/orb.png~RC(690039,c30074,ec008c > 007f00,00ff00,000000,000000)

The IDs of the color ranges may be the lowercased English name of the palette's base color (e.g. 'red', 'brown', etc.). They may also be numeric color indices from the palette WML included with the game, but this is not recommended.

SEPIA: Sepia function

(Version 1.13.0 and later only) May be used to give to the image a sepia tint (like in old pictures).

~SEPIA()

SWAP: Channel Swap function

(Version 1.13.1 and later only) May be used to swap the RGBA channels of an image.

~SWAP( r, g, b ) ~SWAP( r, g, b, a )

  • r, g, b, a: each of these arguments may have a value equal to red, green, blue or alpha. The RGBA channels of the original image will be exchanged accordingly (for example, ~SWAP(blue,green,red) swaps the blue and red channels).

TC: Team-Color function

In Wesnoth version 1.2, the only Image Path Function was ~TC(), which took two comma-separated parameters: the team number and the source color palette. The valid values for both of these parameters are defined in the file data/team-colors.cfg

~TC( team number , source color palette )

  • team number - this is the first parameter, a number 1-9 signifying the team number of a unit. Number 1 typically means the red team, 2 typically means the blue team, and so on (unless the scenario color settings for any side have been altered).
  • source color palette - the second parameter is a source color palette, usually magenta. Do not surround this parameter with quotes.

Transformations

FL: Flip function

May be used to flip an image horizontally and/or vertically.

~FL( optional argument list )

  • vertical - if the string "vert" is found anywhere in the argument list, the image will be flipped vertically.
  • horizontal - if the string "horiz" is found anywhere in the argument list, the image will be flipped horizontally.
  • if the argument list is empty, the image will only be flipped horizontally.

ROTATE: Rotate function

May be used to rotate an image.

~ROTATE( degrees )

  • degrees - The number of degrees by which the image will be rotated. Positive numbers indicate clockwise rotation, while negative numbers indicate counter-clockwise. (Zero indicates no rotation.)

If the number of degrees is omitted, a quarter turn (90 degrees) clockwise is assumed.

SCALE: Image-scaling function

Scales a graphic up or down.

~SCALE( new_width, new_height )

The new_width and new_height parameters are taken as the image's original width or height, respectively, if one of them happens to be zero. Negative values are treated in the same way, but an error is printed in stderr. This uses the bilinear interpolation algorithm.

SCALE_INTO function

(Version 1.13.5 and later only)

Similar to SCALE, but preserves aspect aspect ratio, scaling to the minimum extent required to fit into the specified area. The resulting image will have the specified width or the specified height, but not necessarily both.

SCALE_SHARP function

(Version 1.13.0 and later only)

Scales functions using a nearest neighbor algorithm. Specify width and height. (It has the same syntax as ~SCALE.)

~SCALE_SHARP(200,300)

SCALE_INTO_SHARP function

(Version 1.13.5 and later only)

Like SCALE_INTO, but uses nearest neighbor algorithm instead of bilinear interpolation.

XBRZ function

(Version 1.13.0 and later only)

Scales functions using the XBRZ algorithm. You may scale things up either 2x, 3x, 4x, or 5x. The scaling tries to preserve the pixel art nature.

~XBRZ(n)

Cut-paste-extend

BLIT: Blit function

Blit (superimpose) the parameter image on the main image. Example: peasant.png~BLIT(hat.png,30,10)

~BLIT(src,x,y)

  • src: an image file used as source for the blit, other image path functions can be used there.
  • x,y: top-left corner coordinates where to blit. If missing assume (0,0).

CROP: Crop function

Extracts a rectangular section of an image file.

~CROP(x,y,width,height)

  • x,y: top-left corner coordinates for the rectangular section extracted. Must be greater or equal than zero, and inside the image's bounds.
  • width: width of the selected region. Must be less than or equal to the original image's width, and must not be negative.
  • height: height of the selected region. Must be less than or equal to the original image's height, and must not be negative.

CROP_TRANSPARENCY

(Version 1.17.26 and later only) Removes any transparent padding from around an image.

~CROP_TRANSPARENCY()

PAD: Pad function

(Version 1.19.17 and later only) Extends side(s) of an image with transparent pixels.

~PAD(..)

  • called with a single number like ~PAD(10) and it will add a 10 pixel padding to every side.
  • called with keys (top, t, right, r, bottom, b, left, l) like ~PAD(bottom=10, t=5) and it will pad those sides by that much.

Can be used to create a fake offset by padding one side of an image in order to push it in the opposite direction.

MASK: Mask function

Remove parts of the main image using the parameter image as a mask. Example: grass.png~MASK(circle.png) will give a circle of grass.

~MASK(mask,x,y)

  • mask: an image file used as mask, other image path functions can be used there.
  • x,y: top-left corner coordinates where to put the mask. Parts ouside of the mask are considered transparent. If missing assume (0,0).

Only the alpha channel of the mask is used and each alpha value will be the maximum alpha of the resulting image. This means that the fully-transparent parts of the mask will erase the corresponding parts of the image, but also that a semi-transparent mask will create a semi-transparent image.

Opacity

ADJUST_ALPHA

(Version 1.13.? and later only)

Alters the alpha of the image according to a WFL formula. The formula must output an integer from 0 to 255 giving the alpha across the canvas. It is evaluated for every pixel and may use the following variables: x, y, red, green, blue, alpha, width, height. (Version 1.15.0 and later only) The variables u and v are also supported now, evaluating to normalized texture coordinates (in the range 0..1); these are equivalent to x/width and y/height respectively.

~ADJUST_ALPHA(formula).

The context object for the formula is a pixel object.

O: Opacity modifying function

Changes an image's opacity at render time.

~O( factor or percentage% )

If the argument includes the percentage symbol (%), it will be treated as a percentage of full (real) opacity; an image will be displayed at its native opacity with ~O(100%).

Without the percentage symbol, the argument is assumed to be a factor by which the image's native opacity should be multiplied. Thus, ~O(0.5) and ~O(50%) are equivalent forms of specifying to reduce an image's opacity by half.

PLOT_ALPHA

(Version 1.13.0 and later only)

At each pixel, the color is replaced with a grey-tone reflecting the alpha value at that pixel, and the new image is fully opaque. Useful for plotting the alpha to help debug an IPF or inspect a sprite.

~PLOT_ALPHA()

WIPE_ALPHA

(Version 1.13.0 and later only)

At each pixel, the alpha value is discarded and the pixel is made fully opaque. Useful again for diagnostics.

~WIPE_ALPHA()

Background coloring function

Sets the color of all the (semi-)transparent pixels of the image.

~BG(r,g,b)

Miscellaneous

BL: Blurring function

Blurs a graphic at render time using the same algorithm used for in-game dialogs.

~BL( radius )

CHAN: General function

(Version 1.13.7 and later only)

This function allows you to do pretty much anything. It takes up to four comma-separated formulas, one each for the red, green, blue, and alpha channels. Each formula functions exactly the same as the formula for ADJUST_ALPHA, but the output integer is used for the corresponding channel rather than always the alpha channel. Do not surround the formula in $(...), since that will erase the self variable.

~CHAN(formula, formula, formula)

The context object for each of the formulas is a pixel object with the following properties:

  • x, y: coordinates of the pixel, from the top left
  • u, v: (Version 1.15.0 and later only) normalized coordinates in the range [0,1]
  • width, height: size of the image canvas
  • red, green, blue, alpha: components of the pixel colour

DARKEN: Removed function

(Version 1.13.7 and later only) This function has been removed. Use a ~BLIT(misc/tod-dark.png) call instead.

Puts a time-of-day schedule overlay (misc/tod-dark.png) on the image, which must be large enough to accommodate it.

~DARKEN()

BRIGHTEN: Removed function

(Version 1.13.7 and later only) This function has been removed. Use a ~BLIT(misc/tod-bright.png) call instead.

Puts a time-of-day schedule overlay (misc/tod-bright.png) on the image, which must be large enough to accommodate it.

~BRIGHTEN()

NOP: Null function

Does nothing.

~NOP()

Pseudo IPFs

The following functions are ignored by the IPF image modification module, but used by other Wesnoth components. They only work in special areas.

NO_TOD_SHIFT: Disabling ToD

(Version 1.13.8 and later only)

This is used by the terrain renderer and prevents terrain and item images from being affected by ToD lighting. This is in particular useful when placing unit images as items, as they will look the same as when placed as unit.

~NO_TOD_SHIFT()

RIGHT: Display portraits on the right

(Version 1.5.8 and later only)

This is used by the [message] interface action and can be used to show a portrait on the right side of the screen.

~RIGHT()

Creating an image file from IPFs

The big advantage of Image Path Functions is that they allow you to alter an image without needing a new image file. However, you can also save the result into a new image file using Wesnoth's command line option --render-image'.

Assuming you find a way to open your computer's terminal:

wesnoth --render-image "units/human-peasants/ruffian.png~RC(magenta>green)~BLIT(units/human-peasants/woodsman.png~RC(magenta>lightblue),18,12)" /tmp/new_image_file.png

Or on Windows:

"C:\Path\to\Battle for Wesnoth\wesnoth.exe" --render-image "units/human-peasants/ruffian.png~RC(magenta>green)~BLIT(units/human-peasants/woodsman.png~RC(magenta>lightblue),18,12)" new_image_file.png

Use cases include:

  • Experimenting with Image Path Functions. If none of the images are from an add-on, adding --noaddons will speed this up.
  • If a new Image Path Function is added to the development version of Wesnoth, add-ons for older Wesnoth versions can use a generated image instead.
  • In case you want to use this anywhere out of Wesnoth. On a website, in Project Haldric, …

See Also

  • FancyAddonIcons - Tips and tricks for advanced Image Path Function manipulation
  • DataURI - An image path may also contain the image directly, as a Base64 encoded string
  • Wespal - Tool to preview unit recoloring. Covers the effects of the RC, TC and PAL functions.
  • src/image_modifications.cpp - file where IPFs are implemented