Skip to content

ImageCompose

Status: Stable

documented, exercised by the test suite and/or worked examples, with no known limitations recorded.

Description

ImageCompose[base, over]

alpha-composites over onto base, centred, keeping base's size and clipping whatever falls outside. ImageCompose[base, over, {x, y}] centres the overlay at {x, y} in image coordinates -- x from the left, y from the BOTTOM. ImageCompose[base, {over, a}] scales the overlay's opacity by a. A grey image composed with a colour one produces colour: grey means the same value in every channel, so it is replicated rather than zero-padded.

Examples (19)

Every input below was run against the current Mathilda build and its output recorded.

Basic Examples (7)

In[1]:= a = Image[Table[N[(i + j)/32], {i, 1, 16}, {j, 1, 16}], "Real"];

In[2]:= red = Image[Table[{1., 0., 0.}, {i, 1, 6}, {j, 1, 6}], "Real"];

In[3]:= ImageCompose[a, red]
Out[3]= -Image-

In[4]:= ImageDimensions[ImageCompose[a, red]]
Out[4]= {16, 16}

In[5]:= ImageChannels[ImageCompose[a, red]]
Out[5]= 3

In[6]:= ImageCompose[a, red, {4, 4}]
Out[6]= -Image-

In[7]:= ImageCompose[a, {red, 0.4}]
Out[7]= -Image-

Applications (3)

In[8]:= a = Image[Table[N[(i + j)/32], {i, 1, 32}, {j, 1, 32}], "Real"];

An edge map laid over the image it came from

In[9]:= ImageCompose[a, {EdgeDetect[a], 0.6}]
Out[9]= -Image-

A blurred copy blended halfway: the classic soft-focus composite

In[10]:= ImageCompose[a, {GaussianFilter[a, 3], 0.5}]
Out[10]= -Image-

Properties & Relations (5)

In[11]:= a = Image[Table[N[(i + j)/32], {i, 1, 16}, {j, 1, 16}], "Real"];

In[12]:= red = Image[Table[{1., 0., 0.}, {i, 1, 6}, {j, 1, 6}], "Real"];

The size is the base's, whichever way round the two are given

In[13]:= {ImageDimensions[ImageCompose[a, red]], ImageDimensions[ImageCompose[red, a]]}
Out[13]= {{16, 16}, {6, 6}}

Outside the overlay, the grey base is replicated across all three channels

In[14]:= Module[{d = ImageData[ImageCompose[a, red]]}, d[[1, 1, 1]] === d[[1, 1, 2]] && d[[1, 1, 2]] === d[[1, 1, 3]]]
Out[14]= True

At zero opacity the overlay contributes nothing, even where it covers

In[15]:= Module[{d = ImageData[ImageCompose[a, {red, 0.}]]}, d[[8, 8, 1]] === d[[8, 8, 2]]]
Out[15]= True

Applications (4)

A 3x3 black field

In[16]:= base = Image[{{0., 0., 0.}, {0., 0., 0.}, {0., 0., 0.}}];

Compositing keeps the base's size

In[17]:= ImageDimensions[ImageCompose[base, Image[{{1.}}]]]
Out[17]= {3, 3}

A single white pixel lands at the centre

In[18]:= ImageData[ImageCompose[base, Image[{{1.}}]]]
Out[18]= {{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}}

Grey overlay on colour base stays colour

In[19]:= ImageChannels[ImageCompose[Image[{{{0., 0., 0.}}}], Image[{{1.}}]]]
Out[19]= 3

Implementation notes

Algorithm. builtin_imagecompose alpha-composites over onto base. The result keeps the base's size — composition is "draw on this", not "make something bigger" — and any part of over falling outside is clipped. The overlay is centred by default; ImageCompose[base, over, {x, y}] places its centre at image coordinate {x, y} (x from the left, y from the bottom), which the storage-order flip oy = base.h - py - over.h/2 converts to a row offset. ImageCompose[base, {over, opacity}] scales the overlay's alpha by a constant.

Per destination pixel the standard over operator runs: out = o·α + b·(1−α) for each colour channel, with α the overlay's own alpha at that point times the opacity. Channel counts are reconciled once by promote, which combines in the larger colour count — a grey overlay on a colour base produces colour, since grey means "the same in every channel" and is replicated rather than zero-padded. The result carries an alpha channel only if the base did (out_alpha = base_alpha + α·(1 − base_alpha)); compositing onto an opaque image stays opaque.

Data structures. Two decoded Img buffers; a fresh base.w · base.h · out_channels buffer, wrapped by image_build_real as a packed "Real" image (every image head returns a packed buffer — make check-image-packing). sample handles grey-to-colour replication and absent alpha in one accessor.

Complexity / limits. O(base.w · base.h · channels). Placement outside the base is clipped, not an error; the opacity constant must lie in [0, 1].

  • Protected.
  • The result keeps the base's size and clips whatever falls outside: composition is "draw on this", not "make something bigger".
  • A grey image composed with a colour one produces colour. Grey means the same value in every channel, so it is replicated, never zero-padded — padding would turn a grey pixel red.
  • The result carries alpha only if the base did: compositing onto an opaque image gives an opaque image.

Attributes: Protected.

References

Notes & additional examples

Notes

ImageCompose[base, over] draws over onto base with the standard over operator, centred and keeping the base's dimensions; whatever falls outside is clipped. ImageCompose[base, over, {x, y}] places the overlay's centre at image coordinate {x, y} — x from the left, y from the bottom, Mathematica's convention. ImageCompose[base, {over, a}] fades the overlay by a constant opacity a.

A grey overlay on a colour base produces colour: grey means the same value in every channel, so it is replicated rather than zero-padded (which would turn a grey pixel red). The result carries alpha only if the base did.