SVG feComposite: confronta grafica con in, out e xor
Confronta input dei filtri SVG con in, out e xor, prova ordine e alfa parziale e conserva i tracciati quando un’apertura visiva non è geometria modificabile.
In questa pagina
- Assegna un nome a entrambi gli input prima di scegliere l’operatore
- Allinea esplicitamente la seconda grafica
- Esegui il confronto originale completo
- Confronta pittura e geometria separatamente
- L’opacità parziale cambia il significato di un’apertura
- Consegna un effetto di filtro o crea contorni reali
- Domande frequenti
- Fonti
SVG feComposite combina due input renderizzati. Con input completamente opachi, in mantiene il primo nella sovrapposizione, out lo mantiene fuori e xor combina entrambi al di fuori della sovrapposizione comune. Queste operazioni cambiano la pittura durante il rendering. Non riscrivono i tracciati sorgente in un’intersezione o differenza modificabile.
La distinzione conta quando una sovrapposizione sembra un’apertura ma la consegna richiede contorni reali. L’esempio seguente confronta due nostre forme asimmetriche originali, inverte gli input e verifica la trasparenza parziale. Conserva la grafica sorgente accanto al risultato filtrato.
Assegna un nome a entrambi gli input prima di scegliere l’operatore
Il riferimento MDN su feComposite descrive un’operazione per pixel nello spazio dell’immagine. in nomina il primo input, in2 il secondo. Assegna nomi espliciti ai risultati intermedi, così una modifica della catena di filtri non cambia silenziosamente gli operandi.
Per interni opachi, queste tre operazioni sono facili da confrontare:
| Operazione | Primo input A, secondo input B | Cosa cambia invertendo gli input |
|---|---|---|
in | Pittura di A nella sovrapposizione | La sovrapposizione assume invece la pittura di B |
out | Pittura di A fuori da B | La pittura di B fuori da A è una regione diversa |
xor | Entrambi gli input fuori dalla sovrapposizione opaca comune | Restano le stesse regioni non sovrapposte |
Lo stesso attributo operator compare anche su altre primitive di filtro con valori diversi. Esplicita il contesto di composizione: il riferimento MDN su operator lo distingue dalle operazioni morfologiche.

Allinea esplicitamente la seconda grafica
Il primo operando A è un blocco a gradini verde petrolio. B è un aquilone obliquo ocra. Entrambi usano lo stesso viewBox 0 0 240 160. B si estende oltre il riquadro locale di A, quindi usare i limiti di A come regione del filtro sarebbe una cattiva ipotesi iniziale.
Il filtro usa filterUnits="userSpaceOnUse" per la regione esplicita x=0, y=0, width=240, height=160. Il riferimento MDN su filterUnits spiega la scelta delle coordinate. Impostiamo anche primitiveUnits="userSpaceOnUse" e diamo al secondo input le stesse coordinate dell’intera cornice.
B è un URL di dati SVG autonomo passato tramite feImage, con nome del risultato operandB. Entra nel filtro come input immagine; il suo tracciato non viene inserito come nuovo figlio diretto della grafica filtrata. Il riferimento MDN su feImage descrive il comportamento dell’input immagine.
Il filtro seleziona esplicitamente sRGB. Il valore predefinito di queste primitive è linearRGB, come documentato nel riferimento feComposite. Né quel valore né il nome dell’operatore forniscono un’operazione di modifica dei tracciati.
Esegui il confronto originale completo
Salvalo come starter.html e servi la cartella tramite HTTP locale, per esempio con python3 -m http.server 8766 --bind 127.0.0.1. Apri http://127.0.0.1:8766/starter.html; usa un’altra porta libera se necessario.
La pagina crea due originali più sette casi filtrati per ciascuna di due dimensioni esplicite. Ogni ID del filtro include caso e larghezza, così più SVG inline nello stesso documento hanno riferimenti univoci. Ogni collegamento Save SVG conserva il filtro autonomo e il suo input B codificato.
<!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>Il codice conserva lo stesso tracciato diretto A anche quando gli input dell’operatore sono invertiti. Per esempio, b-in-a cambia feComposite in in="operandB" e in2="SourceGraphic"; non sostituisce l’elemento sorgente filtrato con B. Questo rende visibile l’ordine degli operandi senza alterare la geometria A sottostante.
L’ispezione dei pixel legge qui un canvas dipinto da ogni SVG generato. Il file scaricabile resta l’SVG filtrato. Non è un nuovo tracciato booleano o una conversione PerfectVector.
Confronta pittura e geometria separatamente
Abbiamo eseguito esattamente questa pagina in un ambiente Chrome a 120 × 80 e 240 × 160, salvato tutti i 18 SVG e riaperto come immagini nello stesso browser. Le dimensioni visualizzate sono input espliciti, non un’affermazione su due dispositivi fisici.
Tre posizioni interne usano il sistema di coordinate originale: solo A (40,40), solo B (200,84) e sovrapposizione (120,84). Sono stati osservati i seguenti valori alfa a entrambe le dimensioni con operandi opachi:
| Input del filtro e operatore | Alfa solo A | Alfa solo B | Alfa sovrapposizione |
|---|---|---|---|
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 |
Le righe in condividono una sovrapposizione opaca ma differiscono per colore: con A primo era verde petrolio (23,107,91,255), con B primo ocra (212,165,58,255). Il campione esterno (230,150) restava sempre trasparente. Sono pixel interni selezionati, non un test completo della copertura dei bordi o della compatibilità.
Ogni file filtrato conservava l’esatta stringa d originale di A e lo stesso SHA-256. Il getBBox() geometrico locale restava x=24, y=24, width=168, height=112. Quel riquadro descrive il tracciato sorgente; non è il riquadro dei pixel visibili del filtro. Anche il tracciato B codificato restava invariato. Un risultato filtrato può quindi apparire diverso mentre entrambi i contorni creati restano intatti.
Gli originali salvati hanno un tracciato diretto e nessuna immagine di filtro. Ogni file filtrato ha un tracciato diretto A più un feImage che trasporta l’SVG separato di B con un solo tracciato. Non viene introdotto un normale elemento raster image. Un’operazione renderizzata nello spazio dell’immagine e operandi sorgente vettoriali possono coesistere; il solo inventario della sorgente non significa che il risultato sia diventato geometria combinata modificabile.
L’opacità parziale cambia il significato di un’apertura
L’ultimo caso rende B opaco a metà lasciando A opaco, poi applica A out B. La sovrapposizione non diventa vuota. A entrambe le dimensioni, il valore RGBA osservato era (22,106,90,127): verde petrolio parzialmente trasparente, con arrotondamenti dalla catena di rendering e lettura.
Per out, l’alfa di output è il primo alfa moltiplicato per uno meno il secondo. Per in, è il loro prodotto. La definizione di composizione Filter Effects definisce le operazioni con colori premoltiplicati e alfa. B opaco può rimuovere la pittura sovrapposta di A; B parzialmente trasparente ne lascia una parte.
Esamina il risultato sullo sfondo effettivo. Una regione chiara sul bianco può essere pittura traslucida anziché un foro completamente trasparente. Anche i pixel dei bordi antialias richiedono verifica visiva; il campione interno non promette alfa zero per ogni pixel del confine. Per un lavoro separato di rimappatura dell’opacità, consulta la guida alle soglie alfa SVG.
Consegna un effetto di filtro o crea contorni reali
Conserva questo filtro quando il renderer ricevente deve riprodurre la composizione visiva. Mantieni i file A e B originali e controlla l’SVG filtrato riaperto nella destinazione effettiva. La riapertura riuscita nel nostro browser non certifica altri renderer o macchine di produzione.
Se la consegna richiede contorni combinati selezionabili o un’apertura pronta per il taglio, esegui e controlla una vera modifica dei tracciati o un’operazione booleana nel procedimento previsto. La pittura visibile cambiata qui non crea quella geometria. La guida clipPath contro maschera chiarisce una distinzione correlata sulla visibilità; la guida alla separazione dei gruppi SVG aiuta quando la grafica visualizzata non è l’oggetto modificabile atteso.
Se la clipart esiste solo come pixel e ti servono forme sorgente modificabili, prepara un SVG di clipart con PerfectVector, esamina contorni e aperture e conserva il master. Applica e verifica separatamente il filtro o l’operazione sui tracciati desiderati. La vettorializzazione non trasforma la sovrapposizione visiva di questo filtro in un contorno di produzione verificato.
Domande frequenti
feComposite out elimina la geometria del tracciato sovrapposto? No. Cambia la pittura renderizzata usando l’alfa del secondo input. Nei nostri file filtrati, dati originali del tracciato A e limiti geometrici locali restavano invariati anche dove la pittura sovrapposta diventava trasparente.
Perché scambiare in e in2 cambia il risultato? Identificano primo e secondo input. In mantiene la pittura del primo nell’opacità del secondo; out mantiene il primo fuori. I nostri casi in invertiti condividono la sovrapposizione opaca ma mostrano colori diversi, mentre i casi out invertiti conservano regioni diverse.
xor crea sempre una sovrapposizione completamente vuota? La sovrapposizione interna completamente opaca era vuota nei nostri casi xor. Alfa parziale e bordi antialias richiedono controlli specifici; i diagrammi di insiemi di forme opache non descrivono ogni pixel traslucido.
Posso inviare direttamente l’apertura filtrata come tracciato di taglio modificabile? Un risultato visivo di filtro non è nuova geometria booleana creata. Conserva le forme originali, crea e controlla i contorni richiesti nel procedimento di tracciati previsto e verifica separatamente applicazione ricevente e requisiti di produzione.
Fonti
- MDN: feComposite — Ruoli degli input nello spazio dell’immagine, operatori e spazio colore predefinito del filtro.
- MDN: operator — Valori degli operatori di composizione e contesto morfologico separato.
- MDN: filterUnits — Sistema di coordinate della regione del filtro.
- MDN: feImage — Input immagine nella catena di filtri.
- W3C: Composizione Filter Effects — Definizioni della composizione di colore premoltiplicato e alfa.
Parti da una tua clipart raster? Crea un master SVG modificabile, controlla contorni e aperture, poi conservalo mentre verifichi nella destinazione la composizione visiva scelta o il risultato di tracciati creato separatamente.
Altro dal blog

Ritaglia un SVG definitivamente senza tracciati nascosti
Ritaglia i riempimenti SVG con intersezioni reali, preserva colori e aperture, poi controlla nel file salvato la geometria che una clip nasconderebbe soltanto.

Inkscape: Object to Path e Stroke to Path a confronto
Confronta Object to Path e Stroke to Path di Inkscape sullo stesso cerchio. Scopri quale conserva un tratto modificabile, quale crea una banda piena e che cosa controllare.
