From The Mana World
m (Jaxad0127 moved page Image dyeing to Dev:Image dyeing)
m (Move page script moved page Dev:Image dyeing to Development:Image dyeing: Rename Dev: to Development: so the miraheze import works)
 
(19 intermediate revisions by 3 users not shown)
Line 1: Line 1:
==Simple colors and palettes==
==Simple colors and palettes==


A pixel has a simple color if it is not black and if its non-zero RGB components are all equal. Or described in terms of the HSV color model: it has a hue divisible by 60, full saturation, and any volume other than zero.
A pixel has a simple color if it is not black and if its non-zero RGB components are all equal. Or described in terms of the HSV color model: it has a hue divisible by 60, full saturation, and any value other than zero.


There are seven simple colors:
There are seven simple colors:
Line 15: Line 15:
For a given color, there are 255 different intensities (from 1 to 255). For RGB, the non-zero value is the intensity. For HSV, the volume is the intensity, scaled to 255.
For a given color, there are 255 different intensities (from 1 to 255). For RGB, the non-zero value is the intensity. For HSV, the volume is the intensity, scaled to 255.


A palette is a sequence of RGB colors, for example <code>#8c4b41,da9041,ffff41</code>. An intensity of 255 becomes color <code>#ffff41</code>. An intensity of 0 is left unchanged (as black, <code>#000000</code>). Intensities with no explicit color are linearly interpolated between the two closest value. Black is implicitly the first color of the palette. For example:
A palette is a sequence of RGB colors, for example <code style="background-color:#8c4b41;;color:lightgrey">#8c4b41</code>,<code style="background-color:#da9041;color:#825525">da9041</code>,<code style="background-color:#ffff41;">ffff41</code>. An intensity of 255 becomes color <code style="background-color:#ffff41;">#ffff41</code>. An intensity of 0 is left unchanged (as black, <code style="background-color:#000;color:lightgrey">#000000</code>). Intensities with no explicit color are linearly interpolated between the two closest value. Black is implicitly the first color of the palette. For example:
{|
{|
! intensity
! intensity
Line 21: Line 21:
|-
|-
|50
|50
|<code>#522C26</code>
|<code style="background-color:#522C26;color:lightgrey">#522C26</code>
|-
|-
|85
|85
|<code>#8c4b41</code>
|<code style="background-color:#8c4b41;color:lightgrey">#8c4b41</code>
|-
|-
|100
|100
|<code>#995741</code>
|<code style="background-color:#995741;color:lightgrey">#995741</code>
|-
|-
|170
|170
|<code>#da9041</code>
|<code style="background-color:#da9041;color:#825525">#da9041</code>
|}
|}


Line 37: Line 37:
Pixels with complicated colors or without any dedicated palette are left unchanged by the dye process. The system can dye up to 1785 different colors.
Pixels with complicated colors or without any dedicated palette are left unchanged by the dye process. The system can dye up to 1785 different colors.


==Specifying palettes==
==Dye Channels==
==='''RGBCMYW''' Dyes===


Whenever an image (usually a <code>png</code> file) is specified in an <code>xml</code> file, a palette can be appended to its name. The image is then automatically dyed on loading. For example, if one changes an image resource from <code>foo.png</code> to <code>foo.png|W:#ffff00</code>, then all the gray pixels of <code>test.png</code> will be replaced by shades of yellow, as described above.
Usage:
Single Channel Inline xml: image.png|R:#ColorCode
Multi-Channel Inline xml: image.png|R:#ColorCode;B:#ColorCode
Single Channel Preset xml: image.png|R
Multi-Channel Preset xml: image.png|R;B


Several palettes (one per simple color) can be appended to an image. For example, green and red pixels are recolored independently for image <code>foo.png|G:''palette1'';R:''palette2''</code>.
==='''S'''wap dye===
This swaps a single specific color on a channel regardless of transparency for another


Palettes can either be specified as the name of a file containing a palette (format not yet defined) or directly defined as a color sequence. A '''#''' symbol (often called ''pound'', ''hash'', or ''sharp'') is prefixed to a color sequence, so that the system understands that this is a color, not another file.
Use:
Inline xml: image.png|S:#StartingColor,#ResultColor;
Preset xml: image.png|S


==Dyeing sprites==
Example:
image.png|S:#FF0000,#00FF00;
Starting color: #FF0000 (pure red)
Result color: #00FF00 (pure green)


When indicating the dyeable colors in an image, some palettes can be left unspecified. For example, the resource name <code>foo.png|G;R:''palette1'';Y</code> means that green, red, and yellow, pixels of the image have to be dyed. But no palettes are specified for green and yellow pixels.
==='''A'''lpha dye===
This swaps a single specific color on a channel taking transparency into account


These palettes will be specified at a higher level. If the <code>foo.png</code> file is part of a sprite description named <code>bar.xml</code>. Then palette specifications can be appended to the file name, e.g. <code>bar.xml|''palette2'';''palette3''</code>. These additional palettes are then propagated to any image loaded by <code>bar.xml</code> with unspecified palettes. So the <code>foo.png</code> is finally recolored with the dye <code>G:''palette2'';R:''palette1'';Y:''palette3''</code>.
Use:
Inline Xml: image.png|S:#StartingColor,#ResultColor;
Preset Xml: image.png|S
 
Example:
image.png|S:#FF000088,#00FF0088;
Starting color: #FF000088 (pure red with ~half transparency)
Result color: #00FF0088 (pure green with ~half transparency)


===One-channel example===
===One-channel example===
Here is a simple example taken from actual game data. The <code>data/monsters.xml</code> file contains the descriptions of all the monsters. For black scorpions, the definition begins with
Here is a simple example taken from actual game data. The <code>data/monsters.xml</code> file contains the descriptions of all the monsters. For black scorpions, the definition begins with


<syntaxhighlight lang="xml">
<monster id="1009" name="Black scorpion">
<monster id="1009" name="Black scorpion">
    <sprite>monster-scorpion.xml|#0d1313,435a5a,879999,ffffff</sprite>
    <sprite>monster-scorpion.xml|#0d1313,435a5a,879999,ffffff</sprite>
    <sound event="hit">scorpion-hit1.ogg</sound>
    <sound event="hit">scorpion-hit1.ogg</sound>
    ...
    ...
</syntaxhighlight>


The <code>data/graphics/sprite/monster-scorpion.xml</code> then describes the animation of any scorpion, whatever its color. It contains this line:
The <code>data/graphics/sprite/monster-scorpion.xml</code> then describes the animation of any scorpion, whatever its color. It contains this line:


<syntaxhighlight lang="xml">
<imageset name="base" src="graphics/sprites/monster-scorpion.png|W" width="48" height="45" />
<imageset name="base" src="graphics/sprites/monster-scorpion.png|W" width="48" height="45" />
</syntaxhighlight>


The <code>monster-scorpion.png</code> file is a grayscale image, hence the '''W''' color specifier, so that all its pixels are blackened (or dyed to brown or red for other species of scorpions). If it contained some non-gray pixels, these would not be recolored by the palette specified in the <code>monsters.xml</code> file.
The <code>monster-scorpion.png</code> file is a grayscale image, hence the '''W''' color specifier, so that all its pixels are blackened (or dyed to brown or red for other species of scorpions). If it contained some non-gray pixels, these would not be recolored by the palette specified in the <code>monsters.xml</code> file.
Line 73: Line 88:


head-devcap.xml:
head-devcap.xml:
<syntaxhighlight lang="xml">
<imageset name="base" src="graphics/sprites/head-devcap.png|W;R" width="28" height="19" />
<imageset name="base" src="graphics/sprites/head-devcap.png|W;R" width="28" height="19" /></syntaxhighlight>


items.xml:
items.xml:
<syntaxhighlight lang="xml">
<sprite>head-devcap.xml|#22ff22,ffffff;#9999ff</sprite>
<sprite>head-devcap.xml|#22ff22,ffffff;#9999ff</sprite>
</syntaxhighlight>
 
'''Note: Multi-channel dyeing is broken in version 0.0.24 but has been fixed in later versions'''


==Designing graphics to be dyeable==
==Designing graphics to be dyeable==
Line 88: Line 98:
When you want to use another dye channel than 'W' you can use "color channels" afterwards and remove one or two of the red, green and blue channel completely.
When you want to use another dye channel than 'W' you can use "color channels" afterwards and remove one or two of the red, green and blue channel completely.


==Implementation remarks==
==Test dyes without restarting Manaplus==
===In-Game===
You can reload some of the client-data by typing the following command into chat.
You may have to unequip items then use the command then equip them again.
/cleangraphics


Palettes have to be specified as part of the image and sprite resource names, so that they can be properly cached. If they were not, there would be collisions: All the recolored sprites would have the same color, the first one to be put in the cache for a given sprite definition. Since they are part of the resource names, they may as well be part of the filenames written in <code>.xml</code> files.
===dyecmd===
After version 1.3.10.27 of manaplus: the dyecmd is supported.


==Ideas==
Usage:
dyecmd srcfile dyestring dstfile
dyecmd srcdyestring dstfile


The ability to specify multiple channels for each palette would be nice. It'd be useful in certain cases (like [http://forums.themanaworld.org/viewtopic.php?p=37107#p37107 this robe]) where multiple channels are getting the same palette. One way to indicate it would be to have a comma-separated list of channels before the palette string (example: W,Y:#22ff22,ffffff). &mdash; [[User:Jaxad0127|<span style="color: #160196">Jaxad</span>]][[User Talk:Jaxad0127|<span style="color: #5B038F">0127</span>]] 19:46, 14 July 2008 (CEST)
examples:
[[Category:Art Development]]
dyecmd cottonshirt.png W:#a4b2b2,ffffff test.png
dyecmd "cottonshirt.png|W:#a4b2b2,ffffff" test2.png


==Test dyes without starting client==
From Source
get manaplus source git clone https://bitbucket.org/akaras/manaplus.git
autoreconf -i
./configure
make
src/dyecmd


The dye engine can also be used standalone as console program. The tool can be found in the mana repository (clone git://github.com/mana/mana.git).
[[Category:Development]]
cd tools/dyecmd
cmake .
make
You will find the binary at src/dyecmd. Example use:
# dyecmd <source_image> <target_image> <dye_string>
dyecmd "armor-legs-shorts.png" "armor-legs-shorts2.png" "W:#222255,6666ff"

Latest revision as of 03:56, 27 March 2024

Simple colors and palettes

A pixel has a simple color if it is not black and if its non-zero RGB components are all equal. Or described in terms of the HSV color model: it has a hue divisible by 60, full saturation, and any value other than zero.

There are seven simple colors:

  • Red
  • Green
  • Blue
  • Cyan
  • Magenta
  • Yellow
  • White (gray, that is)

For a given color, there are 255 different intensities (from 1 to 255). For RGB, the non-zero value is the intensity. For HSV, the volume is the intensity, scaled to 255.

A palette is a sequence of RGB colors, for example #8c4b41,da9041,ffff41. An intensity of 255 becomes color #ffff41. An intensity of 0 is left unchanged (as black, #000000). Intensities with no explicit color are linearly interpolated between the two closest value. Black is implicitly the first color of the palette. For example:

intensity color
50 #522C26
85 #8c4b41
100 #995741
170 #da9041

Palettes can have from one to 255 colors.

Pixels with complicated colors or without any dedicated palette are left unchanged by the dye process. The system can dye up to 1785 different colors.

Dye Channels

RGBCMYW Dyes

Usage:

Single Channel Inline xml: image.png|R:#ColorCode
Multi-Channel Inline xml: image.png|R:#ColorCode;B:#ColorCode
Single Channel Preset xml: image.png|R
Multi-Channel Preset xml: image.png|R;B

Swap dye

This swaps a single specific color on a channel regardless of transparency for another

Use:

Inline xml: image.png|S:#StartingColor,#ResultColor;
Preset xml: image.png|S 

Example:

image.png|S:#FF0000,#00FF00; 
Starting color: #FF0000 (pure red)
Result color: #00FF00 (pure green)

Alpha dye

This swaps a single specific color on a channel taking transparency into account

Use:

Inline Xml: image.png|S:#StartingColor,#ResultColor;
Preset Xml: image.png|S

Example:

image.png|S:#FF000088,#00FF0088;
Starting color: #FF000088 (pure red with ~half transparency)
Result color: #00FF0088 (pure green with ~half transparency)

One-channel example

Here is a simple example taken from actual game data. The data/monsters.xml file contains the descriptions of all the monsters. For black scorpions, the definition begins with

<monster id="1009" name="Black scorpion">
    <sprite>monster-scorpion.xml|#0d1313,435a5a,879999,ffffff</sprite>
    <sound event="hit">scorpion-hit1.ogg</sound>
    ...

The data/graphics/sprite/monster-scorpion.xml then describes the animation of any scorpion, whatever its color. It contains this line:

<imageset name="base" src="graphics/sprites/monster-scorpion.png|W" width="48" height="45" />

The monster-scorpion.png file is a grayscale image, hence the W color specifier, so that all its pixels are blackened (or dyed to brown or red for other species of scorpions). If it contained some non-gray pixels, these would not be recolored by the palette specified in the monsters.xml file.

Multi-channel example

Here an example for multi-channel dyeing of an equipment sprite. This example recolors the gray sections of the image to green and the red sections to a gray-blue.

head-devcap.xml:

<imageset name="base" src="graphics/sprites/head-devcap.png|W;R" width="28" height="19" />

items.xml:

<sprite>head-devcap.xml|#22ff22,ffffff;#9999ff</sprite>

Designing graphics to be dyeable

The easy way to make an existing graphic recolorable is to select the parts you want to be recolored and run it through a convert-to-greyscale filter and voilà, you have a recolorable 'W' channel. For optimum results you should then adjust the levels of the grey area so that the darkest color is RGB 127, 127, 127 and the brightest color RGB 255, 255, 255. That way you can very simply define the darkest and the brightest color of the color ramp in items.xml.

When you want to use another dye channel than 'W' you can use "color channels" afterwards and remove one or two of the red, green and blue channel completely.

Test dyes without restarting Manaplus

In-Game

You can reload some of the client-data by typing the following command into chat. You may have to unequip items then use the command then equip them again.

/cleangraphics

dyecmd

After version 1.3.10.27 of manaplus: the dyecmd is supported.

Usage:

dyecmd srcfile dyestring dstfile
dyecmd srcdyestring dstfile

examples:

dyecmd cottonshirt.png W:#a4b2b2,ffffff test.png
dyecmd "cottonshirt.png|W:#a4b2b2,ffffff" test2.png

From Source get manaplus source git clone https://bitbucket.org/akaras/manaplus.git

autoreconf -i
./configure
make
src/dyecmd