SVG feComposite: Grafik mit in, out und xor vergleichen
Vergleiche SVG-Filtereingaben mit in, out und xor, prüfe Operandenreihenfolge und Teiltransparenz und bewahre Quellpfade, wenn eine sichtbare Öffnung keine bearbeitbare Geometrie ist.
Auf dieser Seite
- Benenne beide Eingaben vor der Operatorwahl
- Richte die zweite Grafik ausdrücklich aus
- Führe den vollständigen selbst erstellten Vergleich aus
- Vergleiche Farbe und Geometrie getrennt
- Teiltransparenz verändert die Bedeutung einer Öffnung
- Liefere einen Filtereffekt oder erstelle echte Konturen
- Häufige Fragen
- Quellen
SVG-feComposite kombiniert zwei gerenderte Eingaben. Bei vollständig undurchsichtigen Eingaben behält in die erste Eingabe in der Überlappung, out behält sie außerhalb der Überlappung, und xor kombiniert beide Eingaben außerhalb ihrer gemeinsamen Überlappung. Diese Operationen ändern die Farbe beim Rendern. Sie schreiben die Quellpfade nicht als bearbeitbare Schnittmenge oder Differenz um.
Dieser Unterschied ist wichtig, wenn eine Überlappung wie eine Öffnung aussieht, die Ausgabe aber tatsächliche Konturen benötigt. Das folgende Beispiel vergleicht zwei selbst erstellte asymmetrische Formen, kehrt die Eingaben um und prüft Teiltransparenz. Bewahre die Quellgrafik neben dem gefilterten Ergebnis auf.
Benenne beide Eingaben vor der Operatorwahl
Die MDN-Referenz zu feComposite beschreibt eine pixelweise Operation im Bildraum. in benennt die erste Eingabe, in2 die zweite. Gib Zwischenergebnissen ausdrückliche Namen, damit eine geänderte Filterkette nicht unbemerkt die Operanden verändert.
Bei undurchsichtigen Innenflächen lassen sich diese drei Operationen leicht vergleichen:
| Operation | Erste Eingabe A, zweite Eingabe B | Was das Umkehren der Eingaben ändert |
|---|---|---|
in | Farbe von A in der Überlappung | Die Überlappung trägt stattdessen Bs Farbe |
out | Farbe von A außerhalb von B | Bs Farbe außerhalb von A ist ein anderer Bereich |
xor | Beide Eingaben außerhalb ihrer gemeinsamen undurchsichtigen Überlappung | Dieselben nicht überlappenden Bereiche bleiben |
Dasselbe Attribut operator erscheint auch an anderen Filterprimitiven mit anderen Werten. Halte den Kompositionskontext ausdrücklich fest. MDNs operator-Referenz unterscheidet ihn von Morphologieoperationen.

Richte die zweite Grafik ausdrücklich aus
Unser erster Operand A ist ein blaugrüner gestufter Block. B ist ein ockerfarbenes schiefes Drachenviereck. Beide verwenden dieselbe viewBox 0 0 240 160. B reicht über As lokalen Begrenzungsrahmen hinaus. As Grenzen als Filterbereich anzunehmen wäre daher ein schlechter Ausgangspunkt.
Der Filter verwendet filterUnits="userSpaceOnUse" für seinen ausdrücklichen Bereich x=0, y=0, width=240, height=160. MDNs filterUnits-Referenz erklärt diese Koordinatenwahl. Wir setzen außerdem primitiveUnits="userSpaceOnUse" und geben der zweiten Eingabe dieselben Vollrahmenkoordinaten.
B ist eine eigenständige SVG-Daten-URL, die über feImage mit dem Ergebnisnamen operandB eingebunden wird. Das führt sie dem Filter als Bildeingabe zu. Es fügt Bs Pfad nicht als neues direktes Kindelement der gefilterten Grafik ein. Die MDN-Referenz zu feImage beschreibt dieses Verhalten als Bildeingabe.
Der Filter wählt ausdrücklich sRGB. Der Standard für diese Filterprimitive ist linearRGB, wie die feComposite-Referenz dokumentiert. Weder dieser Standard noch der Operatorname liefert eine Pfadbearbeitungsoperation.
Führe den vollständigen selbst erstellten Vergleich aus
Speichere dies als starter.html und stelle den Ordner über lokales HTTP bereit, etwa mit python3 -m http.server 8766 --bind 127.0.0.1. Öffne http://127.0.0.1:8766/starter.html. Verwende bei Bedarf einen anderen freien Port.
Die Seite erstellt zwei Originale und sieben gefilterte Fälle in jeweils zwei ausdrücklich gewählten Größen. Jede Filter-ID enthält Fall und Breite, sodass mehrere Inline-SVGs im selben Dokument eindeutige Verweise haben. Jeder Link zum Speichern des SVGs erhält den eigenständigen Filter und seine kodierte B-Eingabe.
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Original SVG composite artwork</title>
<style>
body { margin: 24px; font: 16px system-ui; background: #f6f2e8; }
main { display: grid; grid-template-columns: repeat(3, 260px); gap: 18px; }
figure { margin: 0; }
svg { display: block; background: white; border: 1px solid #bbb; }
figcaption { margin: 6px 0; }
pre { white-space: pre-wrap; font-size: 12px; }
</style>
<h1>Original operands and rendered composites</h1>
<main id="cases"></main>
<pre id="report"></pre>
<script>
const A = 'M24 24 H132 V56 H192 V136 H24 Z';
const B = 'M92 8 L216 84 L92 152 L60 84 Z';
const svgNS = 'http://www.w3.org/2000/svg';
const cases = [
{ id: 'a' }, { id: 'b' },
{ id: 'a-in-b', operator: 'in' },
{ id: 'a-out-b', operator: 'out' },
{ id: 'a-xor-b', operator: 'xor' },
{ id: 'b-in-a', operator: 'in', reverse: true },
{ id: 'b-out-a', operator: 'out', reverse: true },
{ id: 'b-xor-a', operator: 'xor', reverse: true },
{ id: 'a-out-half-b', operator: 'out', opacity: 0.5 },
];
function documentSVG(test, width) {
const height = width * 2 / 3;
const id = test.id + '-' + width;
const second = '<svg xmlns="' + svgNS + '" width="240" height="160" viewBox="0 0 240 160">'
+ '<path d="' + B + '" fill="#d4a53a" opacity="' + (test.opacity ?? 1) + '"/></svg>';
const href = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(second);
const first = test.reverse ? 'operandB' : 'SourceGraphic';
const other = test.reverse ? 'SourceGraphic' : 'operandB';
const defs = test.operator ? '<defs><filter id="' + id + '" filterUnits="userSpaceOnUse" primitiveUnits="userSpaceOnUse" x="0" y="0" width="240" height="160" color-interpolation-filters="sRGB">'
+ '<feImage href="' + href + '" x="0" y="0" width="240" height="160" preserveAspectRatio="none" result="operandB"/>'
+ '<feComposite in="' + first + '" in2="' + other + '" operator="' + test.operator + '"/></filter></defs>' : '';
return '<svg xmlns="' + svgNS + '" width="' + width + '" height="' + height + '" viewBox="0 0 240 160">'
+ defs + '<path d="' + (test.id === 'b' ? B : A) + '" fill="' + (test.id === 'b' ? '#d4a53a' : '#176b5b')
+ '"' + (test.operator ? ' filter="url(#' + id + ')"' : '') + '/></svg>';
}
async function run() {
const results = [];
for (const width of [120, 240]) {
for (const test of cases) {
const source = documentSVG(test, width);
const svg = new DOMParser().parseFromString(source, 'image/svg+xml').documentElement;
const figure = document.createElement('figure');
const caption = document.createElement('figcaption');
caption.textContent = test.id + ', ' + width + ' × ' + width * 2 / 3;
figure.append(document.importNode(svg, true), caption);
document.getElementById('cases').append(figure);
const path = figure.querySelector('path');
const bbox = path.getBBox();
const image = new Image();
image.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(source);
await image.decode();
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = width * 2 / 3;
const ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0);
const sample = (x, y) => [...ctx.getImageData(Math.floor(x * width / 240), Math.floor(y * width / 240), 1, 1).data];
const hash = [...new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(path.getAttribute('d'))))]
.map(v => v.toString(16).padStart(2, '0')).join('');
const download = document.createElement('a');
download.href = image.src;
download.download = test.id + '-' + width + '.svg';
download.textContent = 'Save SVG';
figure.append(download);
results.push({ id: test.id, width, height: canvas.height, d: path.getAttribute('d'), dSHA256: hash,
bbox: { x: bbox.x, y: bbox.y, width: bbox.width, height: bbox.height },
directPaths: svg.querySelectorAll('path').length, filterImages: svg.querySelectorAll('feImage').length,
aOnly: sample(40, 40), bOnly: sample(200, 84), overlap: sample(120, 84), outside: sample(230, 150) });
}
}
document.getElementById('report').textContent = JSON.stringify({ A, B, results }, null, 2);
}
run();
</script>
</html>Der Code behält denselben direkten A-Pfad, auch wenn die Operatoreingaben umgekehrt werden. Beispielsweise ändert b-in-a das feComposite zu in="operandB" und in2="SourceGraphic". Es ersetzt das gefilterte Quellelement nicht durch B. Dadurch wird die Operandenreihenfolge sichtbar, ohne As zugrunde liegende Geometrie zu ändern.
Die Pixelprüfung hier liest ein Canvas aus, das aus jedem erzeugten SVG bemalt wurde. Die herunterladbare Ausgabe bleibt das gefilterte SVG. Sie ist weder ein neuer boolescher Pfad noch eine PerfectVector-Konvertierung.
Vergleiche Farbe und Geometrie getrennt
Wir führten genau diese Seite in einer Chrome-Umgebung bei 120 × 80 und 240 × 160 aus, speicherten alle 18 SVGs und öffneten sie im selben Browser erneut als Bilder. Die Darstellungsgrößen sind ausdrückliche Eingaben, keine Aussage über zwei physische Geräte.
Drei innere Abtastpositionen verwenden das ursprüngliche Koordinatensystem: nur A (40,40), nur B (200,84) und Überlappung (120,84). Mit undurchsichtigen Operanden wurden die folgenden Alphawerte bei beiden Größen beobachtet:
| Filtereingaben und Operator | Alpha nur A | Alpha nur B | Alpha der Überlappung |
|---|---|---|---|
A in B | 0 | 0 | 255 |
A out B | 255 | 0 | 0 |
A xor B | 255 | 255 | 0 |
B in A | 0 | 0 | 255 |
B out A | 0 | 255 | 0 |
B xor A | 255 | 255 | 0 |
Die in-Zeilen teilen eine undurchsichtige Überlappung, unterscheiden sich aber in der Farbe. Mit A zuerst war sie blaugrün (23,107,91,255), mit B zuerst ockerfarben (212,165,58,255). Die Außenprobe (230,150) blieb durchgehend transparent. Das sind ausgewählte Innenpixel, kein vollständiger Test der Kantenabdeckung oder Kompatibilität.
Jede gefilterte Datei hatte weiterhin As exakte ursprüngliche d-Zeichenfolge und denselben SHA-256-Wert. Ihr lokales geometrisches getBBox() blieb x=24, y=24, width=168, height=112. Dieser Rahmen beschreibt den Quellpfad. Er ist nicht der Begrenzungsrahmen der sichtbaren Filterpixel. Auch der kodierte B-Pfad blieb unverändert. Ein Filterergebnis kann daher anders aussehen, während beide erstellten Konturen erhalten bleiben.
Die gespeicherten Originale haben einen direkten Pfad und kein Filterbild. Jede gefilterte Datei hat einen direkten A-Pfad sowie ein feImage, das Bs separates Ein-Pfad-SVG trägt. Es wird kein gewöhnliches Raster-image-Element eingefügt. Eine gerenderte Bildraumoperation und Vektorquelloperanden können nebeneinander existieren. Das Quellinventar allein bedeutet nicht, dass das Ergebnis bearbeitbare kombinierte Geometrie geworden ist.
Teiltransparenz verändert die Bedeutung einer Öffnung
Der letzte Fall macht B halb undurchsichtig, während A undurchsichtig bleibt, und wendet dann A out B an. Die Überlappung wurde nicht leer. In beiden Größen war das beobachtete RGBA (22,106,90,127): teilweise transparentes Blaugrün mit Rundung aus Rendering und Auslesung.
Bei out ist das Ausgabealpha das erste Alpha multipliziert mit eins minus dem zweiten Alpha. Bei in ist es ihr Produkt. Die Filter-Effects-Kompositionsdefinition definiert diese Operationen mit vormultiplizierten Farben und Alpha. Ein undurchsichtiges B kann As überlappende Farbe entfernen. Ein teilweise transparentes B lässt einen Teil davon stehen.
Prüfe das Ergebnis vor dem tatsächlichen Hintergrund. Ein heller Bereich auf Weiß kann durchscheinende Farbe statt eines vollständig transparenten Lochs sein. Auch geglättete Kantenpixel musst du visuell prüfen. Die Innenprobe verspricht nicht, dass jeder Grenzpixel Alpha null hat. Für eine separate Aufgabe zur Neuzuordnung der Deckkraft siehe den SVG-Alphaschwellen-Leitfaden.
Liefere einen Filtereffekt oder erstelle echte Konturen
Behalte diesen Filter, wenn der empfangende Renderer die visuelle Komposition reproduzieren soll. Bewahre die ursprünglichen Dateien A und B auf und prüfe das erneut geöffnete gefilterte SVG an seinem tatsächlichen Ziel. Unser erfolgreiches Wiederöffnen im Browser zertifiziert keine anderen Renderer oder Produktionsmaschinen.
Benötigt die Ausgabe auswählbare kombinierte Konturen oder eine schneidefertige Öffnung, führe im vorgesehenen Ablauf eine echte Pfadbearbeitung oder boolesche Operation durch und prüfe sie. Die hier veränderte sichtbare Farbe erzeugt diese Geometrie nicht. Der Leitfaden zu clipPath und mask behandelt einen verwandten Sichtbarkeitsunterschied. Der Leitfaden zum Aufheben von SVG-Gruppierungen hilft, wenn die angezeigte Grafik nicht das erwartete bearbeitbare Objekt ist.
Liegt dein Clipart nur als Pixel vor und brauchst du bearbeitbare Quellformen, bereite mit PerfectVector ein Clipart-SVG vor, prüfe Konturen und Öffnungen und behalte die Masterdatei. Wende den vorgesehenen Filter oder die Pfadoperation separat an und prüfe sie. Vektorisierung macht aus der visuellen Überlappung dieses Filters keine geprüfte Fertigungskontur.
Häufige Fragen
Löscht feComposite out die überlappende Pfadgeometrie? Nein. Es ändert die gerenderte Farbe anhand des Alphas der zweiten Eingabe. In unseren gefilterten Dateien blieben ursprüngliche A-Pfaddaten und lokale Geometriegrenzen unverändert, selbst dort, wo überlappende Farbe transparent wurde.
Warum verändert der Tausch von in und in2 das Ergebnis? Sie bezeichnen erste und zweite Eingabe. In erhält die Farbe der ersten Eingabe innerhalb der Deckkraft der zweiten. Out erhält die erste außerhalb davon. Unsere umgekehrten in-Fälle teilen die undurchsichtige Überlappung, zeigen aber andere Farben. Umgekehrte out-Fälle behalten andere Bereiche.
Macht xor eine Überlappung immer vollständig leer? Die vollständig undurchsichtige innere Überlappung war in unseren xor-Fällen leer. Teilalpha und geglättete Kanten benötigen eine eigene Prüfung. Mengendiagramme undurchsichtiger Formen beschreiben nicht jeden durchscheinenden Pixel.
Kann ich die gefilterte Öffnung direkt als bearbeitbaren Schnittpfad weitergeben? Ein sichtbares Filterergebnis ist keine neu erstellte boolesche Geometrie. Behalte die ursprünglichen Formen, erstelle und prüfe die benötigten Konturen im vorgesehenen Pfadablauf und prüfe empfangende Anwendung und Produktionsanforderungen separat.
Quellen
- MDN: feComposite – Rollen der Bildraumeingaben, Operatorbeschreibungen und standardmäßiger Filterfarbraum.
- MDN: operator – Kompositionsoperatorwerte und separater Morphologiekontext.
- MDN: filterUnits – Koordinatensystem des Filterbereichs.
- MDN: feImage – Bildeingabe in die Filterpipeline.
- W3C: Filter-Effects-Komposition – Kompositionsdefinitionen für vormultiplizierte Farbe und Alpha.
Du beginnst mit eigenem Rasterclipart? Erstelle eine bearbeitbare SVG-Masterdatei, prüfe Konturen und Öffnungen und bewahre sie auf, während du die gewählte visuelle Komposition oder das separat erstellte Pfadergebnis am Ziel prüfst.
Mehr aus dem Blog

SVG dauerhaft zuschneiden, ohne versteckte Pfade
Schneide gefüllte SVG-Pfade durch echte Schnittmengen zu, erhalte getrennte Farben und eine Öffnung und prüfe die gespeicherte Datei auf nur ausgeblendete Geometrie.

Inkscape: Objekt in Pfad oder Kontur in Pfad?
Vergleiche Inkscapes Objekt in Pfad und Kontur in Pfad am selben Kreis. Erfahre, wann die Kontur einstellbar bleibt, wann ein gefülltes Band entsteht und was du danach prüfst.
