ColorReplace¶
Status: Stable
documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
Description¶
ColorReplace[image, old -> new] replaces every pixel within a tolerance ofoldbynew; ColorReplace[image, {r1, r2, ...}] applies several rules and ColorReplace[image, rules, tol] sets the tolerance (default 0.02 -- at 0 only bit-identical colours match, which after any filtering is nothing at all). Distance is Euclidean in RGB, and where rules overlap the NEAREST wins rather than the first, so the answer does not depend on the order they were written. Colours may be RGBColor[r, g, b], GrayLevel[v], a number or {r, g, b}. Replacing a grey image's colour with a non-grey one produces a three-channel image, since flattening the new colour to its luminance would give grey when the caller asked for red. An alpha channel passes through: transparency is not a colour.
Examples (10)¶
Every input below was run against the current Mathilda build and its output recorded.
Basic Examples (4)¶
In[1]:= img = Image[Table[{If[j <= 4, 1., 0.], If[j <= 4, 0., 1.], 0.}, {i, 1, 8}, {j, 1, 8}], "Real"];
In[2]:= ColorReplace[img, RGBColor[1, 0, 0] -> RGBColor[0, 0, 1]]
Out[2]= -Image-
In[3]:= Union[Flatten[ImageData[ColorReplace[img, RGBColor[1, 0, 0] -> RGBColor[0, 0, 1]]]]]
Out[3]= {0.0, 1.0}
In[4]:= ColorReplace[img, {RGBColor[1, 0, 0] -> RGBColor[0, 1, 0], RGBColor[0, 1, 0] -> RGBColor[0, 0, 1]}]
Out[4]= -Image-
Properties & Relations (6)¶
In[5]:= img = Image[Table[{If[j <= 4, 1., 0.], If[j <= 4, 0., 1.], 0.}, {i, 1, 8}, {j, 1, 8}], "Real"];
In[6]:= grey = Image[Table[N[j/8], {i, 1, 8}, {j, 1, 8}], "Real"];
A colour nothing matches leaves the image exactly alone
In[7]:= ImageData[ColorReplace[img, RGBColor[0.5, 0.5, 0.5] -> RGBColor[0, 0, 0]]] === ImageData[img]
Out[7]= True
Grey replaced by colour promotes to three channels; grey by grey does not
In[8]:= {ImageChannels[ColorReplace[grey, GrayLevel[0.5] -> RGBColor[1, 0, 0], 0.1]], ImageChannels[ColorReplace[grey, GrayLevel[0.5] -> GrayLevel[0.], 0.1]]}
Out[8]= {3, 1}
The colour forms are interchangeable
In[9]:= ImageData[ColorReplace[grey, 0.5 -> 0., 0.1]] === ImageData[ColorReplace[grey, GrayLevel[0.5] -> GrayLevel[0.], 0.1]]
Out[9]= True
A tolerance wide enough to reach every colour collapses the image to one
In[10]:= Length[Union[Flatten[ImageData[ColorReplace[img, RGBColor[1, 0, 0] -> RGBColor[0.25, 0.25, 0.25], 2.0]]]]]
Out[10]= 1
Algorithm¶
imagecolor.c -- ColorReplace, ColorQuantize and HistogramTransform.
Three heads that act on an image's COLOURS rather than its geometry, and they share the one thing that makes such operations awkward: a decision made per pixel needs a global view first. Replacing a colour needs a distance rule, quantising needs a palette derived from every pixel, and equalising needs the whole distribution. So each of these makes a pass to gather, then a pass to write — which is why none of them fits the filter machinery in imagefilter.c.
Implementation notes¶
Protected. Colours may beRGBColor[r, g, b],GrayLevel[v], a bare number, or{r, g, b}.- Distance is Euclidean in RGB; the default tolerance is
0.02. At0only bit-identical colours match, which after any filtering is nothing at all. - Where rules overlap the nearest wins, not the first, so the result does not depend on the order they were written in.
- Replacing a grey image's colour with a non-grey one produces a three-channel image: flattening the new colour to its luminance would hand back grey when the caller asked for red. Grey-for-grey does not promote.
- An alpha channel passes through untouched — transparency is not a colour.
Attributes: Protected.
References¶
- Source:
src/imagecolor.c - Specification:
docs/spec/builtins/image-processing.md - Tests:
tests/test_image.c