Have you ever used an image editor to use one graphic to punch a shape in another? Maybe you added one simple graphic to second to create a larger and more complex shape. If so you’ll probably like working with feComposite, which allows you to combine two input images in several ways.
For several weeks I’ve been talking about SVG filter effects. I started with an overview, walked you through the filter element, and then discussed the input and output of filter primitives. The last few weeks I’ve been covering different filter primitives in detail. First were a few simple primitives follow by primitives for working with external images. Last week I talked about merging the results of multiple primitives into a single graphic for display.
Today I want to continue with another filter primitive, feComposite, that’s used to combine the results of two input images.
Note: Firefox doesn’t support svg fragments inside an feImage filter primitive, which means the examples in this post won’t work in Firefox. I’ll see if I can come up with another way to show the examples, but until then you’ll need to view this post in another browser. Sorry for any inconvenience.
The feComposite Filter Primitive
The feComposite primitive can only combine two input images, but it does provide several options for how the inputs are combined and displayed.
The two inputs are specified using the in and in2 attributes, with in being the first image input and in2 being the second. Both can accept any of the keyword values for input a well as the result of another filter primitive inside the same filter.
Where feMerge layered intermediate images one on top of another and then collapsed all the layers into a single graphic, feComposite allows you to choose how the images are combined. You choose how to combine the inputs using the operator attribute and it’s six possible values.
operator = over | in | out | atop | xor | arithmetic
The easiest way to explain what each does is through an example, though I’ll need to set up the example before showing it to you. I’m going to create two triangles, one red and one blue, and position them as you see below. I set an opacity of 0.5 on the red triangle so you can see where both triangles are located.
The red triangle is to the left, the blue triangle is to the right and the purple area at the top is where the two triangles overlap. It’s hard to tell looking at the graphic, but the red triangle displays on top of the blue triangle.
Now for the example. I created both triangles using <path> elements and filled one with red and the other with blue. Because both are inside a <defs> element they won’t display until referenced.
I referenced the triangles inside the filter, each in its own feImage primitive (Remember feImage can reference either an image or SVG fragment). I gave each a result attribute, R for the red triangle and B for the blue triangle.
Finally I set up the feComposite primitive with R (red) as the value of in and B (blue) the value of in2 and then I referenced the filter on a <g> element.
<svg width="100%" height="220" style="outline: 1px solid red">
<path id="blue" d="M 0 0 L 100 0 L 100 100 z" fill="#00f" />
<path id="red" d="M 0 0 L 0 100 L 100 0 z" fill="#f00" />
<filter id="composite" x="0" y="0" width="200%" height="200%">
<feImage xlink:href="#red" result="R" />
<feImage xlink:href="#blue" result="B" />
<feComposite operator="over" in="R" in2="B" />
Notice that I set the operator of feComposite to over and as you can see the red triangle displays over the blue triangle (in displays over in2). Think of each as a separate layer and the composite image places layer R over (or on top of) layer B.
This next result is the same example, except I’ve changed the value of operator to in (Not the same as the in input.). The result is the part of R (red) that’s within the boundaries of B (blue).
Here’s the result of operator=“out” or the part of R (red) that’s outside the boundaries of B (blue).
The result of operator=“atop” is probably not intuitive. It’s the part of R (red) within the boundaries of B (blue) plus the part of B (blue) that’s outside of the boundaries of R (red). You can think of it as the opposite of setting operator to a value of out.
And here’s the result of operator=“xor” which is the part of R (red) that’s outside of B (blue) and the part of B outside of R.
The last operator, arithmetic, needs further explanation and it requires four additional attributes that are meant only for this operator.
The additional attributes are k1, k2, k3, and k4. Each is a coefficient in a formula that determines the value of each pixel in the composited image.
result = k1*in*in2 + k2*in + k3*in2 + k4
The values of k1 through k4 can be any number and if any aren’t set, it’s as though it has a value of 0. If you look at the formula you can see how each is combined with in and/or in2.
Here’s the code for the example again with operator=“arithmetic“ and values of 0.1, 0.2, 0.3, and 0.4 respectively for k1, k2, k3, and k4. The values are arbitrary choices on my part.
<svg width="100%" height="220" style="outline: 1px solid red">
<path id="blue-6" d="M 0 0 L 100 0 L 100 100 z" fill="#00f" />
<path id="red-6" d="M 0 0 L 0 100 L 100 0 z" fill="#f00" />
<filter id="composite-6" x="0" y="0" width="200%" height="200%">
<feImage xlink:href="#red-6" result="R" />
<feImage xlink:href="#blue-6" result="B" />
<feComposite operator="arithmetic" k1="0.1" k2="0.2" k3="0.3" k4="0.4" in="R" in2="B" />
And here’s the result.
You might wonder when you would use the arithmetic operator and how you would determine what values to use for k1 through k4. It’s the most general of the operators and it’s useful in creating dissolve effects or in combination with lighting primitives that I’ll talk about in a later series.
As far as the four coefficients are concerned you’ll likely need some trial and error, but we can look again at the formula to get a sense of what might happen.
result = k1 *in*in2 + k2*in + k3*in2 + k4
Notice that k2 is a coefficient for the in image and k3 is a coefficient for the in2 image. If you set k1 and k4 to 0, you’re left with a formula that will combine k2% of in and k3% of in2.
I’ll leave you with a more practical example. Here I set “in” to my image of Strawberry Fields and I set “in2” to a circle I created and roughly centered within the viewport. I set operator to atop, which will show the image wherever it’s within the boundaries of the circle.
<svg width="100%" height="495" style="outline: 1px solid red">
<circle id="circle" cx="85" cy="62" r="50" />
<filter id="composite-7" x="0" y="0" width="200%" height="200%">
<feImage xlink:href="#circle" result="c" />
<feImage xlink:href="http://www.vanseodesign.com/blog/wp-content/uploads/2013/09/strawberry-fields.jpg" width="100%" height="100%" result="strawberry" />
<feComposite operator="in" in="strawberry" in2="c" />
Here’s the result, which I think you’ll agree is a little more interesting than a couple of triangles.
Hopefully the last example convinced you that feComposite can be a useful primitive, certainly more useful than combining a couple of triangles.
Next week I want to talk about one more primitive that’s used for combining images. I’ll talk about feBlend which blends two images using some of the blend modes you’ve likely used in your favorite image editor.
Download a free sample from my book, Design Fundamentals.
examples did not work in chrome and firefox. writeup is great!
I could make them work in Chrome by copying the paths to g. Thanks for the great post!
g object’s width and height are set depending on the bounding box of its children. So, adding a simple rectangle (
) in it makes it work as well.
All the examples in this page show only red outlines. There is no triangle to show different operators (over | in | out | atop | xor | arithmetic)
All the examples just show white boxes in chrome and firefox on Linux.