> [Site index](https://perfectvector.com/llms.txt) — available pages and descriptions.

# SVG feComposite: porównaj grafikę in, out i xor

> Porównaj wejścia filtrów SVG przez in, out i xor, zbadaj kolejność i częściowe alfa oraz zachowaj ścieżki, gdy widoczny otwór nie jest edytowalną geometrią.

Source: https://perfectvector.com/pl/blog/svg-composite-artwork

Language: pl
Author: Irene Kim
Published: 2026-10-06T08:00:00+09:00
Updated: 2026-10-06T08:00:00+09:00

SVG `feComposite` łączy dwa renderowane wejścia. Dla w pełni nieprzezroczystych wejść `in` zachowuje pierwsze w części wspólnej, `out` zachowuje je poza częścią wspólną, a `xor` łączy oba poza wspólnym obszarem nakładania. Operacje zmieniają malowanie podczas renderowania. Nie przepisują ścieżek źródłowych na edytowalną część wspólną lub różnicę.

Różnica ma znaczenie, gdy nakładanie wygląda jak otwór, lecz wynik wymaga rzeczywistych konturów. Poniższy przykład porównuje dwa oryginalne asymetryczne kształty, odwraca wejścia i sprawdza częściową przezroczystość. Zachowaj grafikę źródłową obok filtrowanego wyniku.

## Nazwij oba wejścia przed wyborem operatora

[Opis feComposite MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/feComposite) przedstawia operację piksel po pikselu w przestrzeni obrazu. `in` nazywa pierwsze wejście, a `in2` drugie. Nadaj wynikom pośrednim jawne nazwy, aby zmiana łańcucha filtrów nie zmieniała po cichu operandów.

Dla nieprzezroczystych wnętrz trzy operacje łatwo porównać:

| Operacja | Pierwsze wejście A, drugie B                          | Co zmienia odwrócenie wejść                      |
| -------- | ----------------------------------------------------- | ------------------------------------------------ |
| `in`     | Malowanie A w części wspólnej                         | Część wspólna otrzymuje zamiast tego malowanie B |
| `out`    | Malowanie A poza B                                    | Malowanie B poza A to inny obszar                |
| `xor`    | Oba wejścia poza ich nieprzezroczystą częścią wspólną | Pozostają te same nienakładające się obszary     |

Ten sam atrybut `operator` pojawia się w innych prymitywach filtrów z innymi wartościami. Zachowaj jawny kontekst kompozycji; [opis operator MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/operator) odróżnia go od operacji morfologicznych.

**Zmień widoczne malowanie**

![Koncepcyjne porównanie nakładającej się kolorowej grafiki i kompozycji z niepomalowaną częścią wspólną](https://perfectvector.com/blog/svg-composite-artwork/overlap-and-paint.webp)

*Ilustracja: nakładające się wejścia mogą pozostawić obszar niepomalowany. Dekoracyjne sylwetki i strzałki są koncepcyjne; dokładne operatory, próbki alfa i niezmienione ścieżki poniżej pochodzą z wykonanego oryginalnego testu przeglądarkowego.*

## Jawnie wyrównaj drugą grafikę

Nasz pierwszy operand A to morskozielony schodkowy blok. B to ochrowy przekrzywiony latawiec. Oba używają tego samego viewBox `0 0 240 160`. B wychodzi poza lokalną obwiednię A, więc przyjęcie granic A jako obszaru filtra byłoby złym założeniem początkowym.

Filtr używa `filterUnits="userSpaceOnUse"` dla jawnego obszaru `x=0`, `y=0`, `width=240`, `height=160`. [Opis filterUnits MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/filterUnits) wyjaśnia wybór współrzędnych. Ustawiamy też `primitiveUnits="userSpaceOnUse"` i nadajemy drugiemu wejściu te same współrzędne pełnego kadru.

B jest samowystarczalnym adresem danych SVG przekazanym przez `feImage`, z nazwą wyniku `operandB`. Wprowadza go do filtra jako wejście obrazu; nie wstawia ścieżki B jako nowego bezpośredniego potomka filtrowanej grafiki. [Opis feImage MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/feImage) przedstawia to zachowanie wejścia.

Filtr jawnie wybiera `sRGB`. Domyślna wartość tych prymitywów to `linearRGB`, zgodnie z opisem feComposite. Ani wartość domyślna, ani nazwa operatora nie dostarczają operacji edycji ścieżek.

## Uruchom kompletne oryginalne porównanie

Zapisz kod jako `starter.html` i udostępnij folder przez lokalne HTTP, na przykład `python3 -m http.server 8766 --bind 127.0.0.1`. Otwórz `http://127.0.0.1:8766/starter.html`; w razie potrzeby użyj innego wolnego portu.

Strona buduje dwa oryginały i siedem filtrowanych przypadków w każdym z dwóch jawnych rozmiarów. Każdy identyfikator filtra zawiera przypadek i szerokość, więc wiele SVG inline w jednym dokumencie ma unikalne odwołania. Każdy link Save SVG zachowuje samowystarczalny filtr i zakodowane wejście B.

```html
<!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>
```

Kod zachowuje tę samą bezpośrednią ścieżkę A nawet po odwróceniu wejść operatora. Na przykład `b-in-a` zmienia `feComposite` na `in="operandB"` i `in2="SourceGraphic"`; nie zastępuje filtrowanego elementu źródłowego przez B. Uwidacznia kolejność operandów bez zmiany bazowej geometrii A.

Kontrola pikseli odczytuje canvas pomalowany z każdego wygenerowanego SVG. Wynikiem do pobrania nadal jest filtrowany SVG. Nie jest to nowa ścieżka logiczna ani konwersja PerfectVector.

## Porównaj malowanie i geometrię oddzielnie

Uruchomiliśmy dokładnie tę stronę w jednym środowisku Chrome przy `120 × 80` i `240 × 160`, zapisaliśmy wszystkie 18 SVG i otworzyliśmy je ponownie jako obrazy w tej samej przeglądarce. Rozmiary wyświetlania są jawnymi wejściami, a nie twierdzeniem o dwóch fizycznych urządzeniach.

Trzy pozycje próbek wewnętrznych używają oryginalnego układu współrzędnych: tylko A `(40,40)`, tylko B `(200,84)` i część wspólna `(120,84)`. Przy nieprzezroczystych operandach zaobserwowano te wartości alfa w obu rozmiarach:

| Wejścia filtra i operator | Alfa tylko A | Alfa tylko B | Alfa części wspólnej |
| ------------------------- | ------------ | ------------ | -------------------- |
| 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                    |

Wiersze `in` dzielą nieprzezroczystą część wspólną, lecz różnią się kolorem: A jako pierwsze dało morskozielony `(23,107,91,255)`, a B jako pierwsze ochrowy `(212,165,58,255)`. Próbka zewnętrzna `(230,150)` pozostawała przezroczysta. To wybrane piksele wnętrza, a nie pełny test pokrycia krawędzi lub zgodności.

Każdy filtrowany plik nadal zawierał dokładny oryginalny ciąg `d` A i zgodny SHA-256. Lokalny geometryczny `getBBox()` pozostał `x=24`, `y=24`, `width=168`, `height=112`. Prostokąt opisuje ścieżkę źródłową, a nie obwiednię widocznych pikseli filtra. Zakodowana ścieżka B także nie zmieniła się. Wynik filtra może więc wyglądać inaczej, podczas gdy oba utworzone kontury pozostają nienaruszone.

Zapisane oryginały mają jedną bezpośrednią ścieżkę i brak obrazu filtra. Każdy filtrowany plik ma jedną bezpośrednią ścieżkę A oraz jeden `feImage` przenoszący oddzielny jednościeżkowy SVG B. Nie wprowadzono zwykłego rastrowego elementu `image`. Renderowana operacja przestrzeni obrazu i wektorowe operandy źródłowe mogą współistnieć; sam inwentarz źródła nie oznacza, że wynik stał się edytowalną połączoną geometrią.

## Częściowa nieprzezroczystość zmienia znaczenie otworu

Ostatni przypadek nadaje B połowę nieprzezroczystości, pozostawia A nieprzezroczyste, a potem stosuje A `out` B. Część wspólna nie stała się pusta. W obu rozmiarach obserwowane RGBA wynosiło `(22,106,90,127)`: częściowo przezroczysty morskozielony, z zaokrągleniami procesu renderowania i odczytu.

Dla `out` alfa wyjściowe to pierwsze alfa pomnożone przez jeden minus drugie alfa. Dla `in` to ich iloczyn. [Definicja kompozycji Filter Effects](https://www.w3.org/TR/filter-effects-1/#feCompositeElement) opisuje te operacje przez kolory premultiplikowane i alfa. Nieprzezroczyste B może usunąć nakładające się malowanie A; częściowo przezroczyste B pozostawia jego część.

Sprawdź wynik na rzeczywistym tle. Jasny obszar na bieli może być półprzezroczystym malowaniem, a nie całkowicie przezroczystym otworem. Wygładzone piksele krawędzi też wymagają oględzin; próbka wnętrza nie obiecuje alfa zero dla każdego piksela granicy. Oddzielne przemapowanie nieprzezroczystości opisuje [poradnik progów alfa SVG](https://perfectvector.com/pl/blog/svg-alpha-threshold).

## Przekaż efekt filtra lub utwórz prawdziwe kontury

Zachowaj filtr, gdy renderer odbiorcy ma odtworzyć widoczną kompozycję. Zachowaj oryginalne pliki A i B i sprawdź ponownie otwarty filtrowany SVG w rzeczywistym miejscu docelowym. Nasze udane otwarcie w przeglądarce nie certyfikuje innych rendererów lub maszyn produkcyjnych.

Jeśli przekazanie wymaga zaznaczalnych połączonych konturów lub otworu gotowego do cięcia, wykonaj i sprawdź prawdziwą edycję ścieżek albo operację logiczną w zamierzonym procesie. Zmienione widoczne malowanie nie tworzy tej geometrii. [Poradnik clipPath a maska](https://perfectvector.com/pl/blog/svg-clippath-vs-mask) omawia pokrewną różnicę widoczności; [poradnik rozgrupowania SVG](https://perfectvector.com/pl/blog/svg-wont-ungroup) pomaga, gdy wyświetlana grafika nie jest oczekiwanym edytowalnym obiektem.

Jeśli clipart istnieje tylko jako piksele i potrzebujesz edytowalnych kształtów źródła, [przygotuj SVG clipartu w PerfectVector](https://perfectvector.com/pl/clipart-to-svg), sprawdź kontury i otwory oraz zachowaj wzorzec. Zastosuj i zweryfikuj zamierzony filtr lub operację ścieżki oddzielnie. Wektoryzacja nie zmienia wizualnego nakładania tego filtra w zweryfikowany kontur produkcyjny.

## Najczęstsze pytania

**Czy feComposite out usuwa nakładającą się geometrię ścieżki?**
Nie. Zmienia renderowane malowanie przez alfa drugiego wejścia. W naszych filtrowanych plikach oryginalne dane ścieżki A i lokalne granice geometrii pozostały bez zmian nawet tam, gdzie nakładające malowanie stało się przezroczyste.

**Dlaczego zamiana in i in2 zmienia wynik?**
Oznaczają pierwsze i drugie wejście. In zachowuje malowanie pierwszego w nieprzezroczystości drugiego; out zachowuje pierwsze poza nim. Odwrócone przypadki in dzielą nieprzezroczystą część wspólną, lecz pokazują inne kolory, a odwrócone out zachowują inne obszary.

**Czy xor zawsze tworzy całkowicie pustą część wspólną?**
Całkowicie nieprzezroczyste wnętrze części wspólnej było puste w naszych przypadkach xor. Częściowe alfa i wygładzone krawędzie wymagają własnej kontroli; diagramy zbiorów nieprzezroczystych kształtów nie opisują każdego półprzezroczystego piksela.

**Czy mogę wysłać filtrowany otwór bezpośrednio jako edytowalną ścieżkę cięcia?**
Wizualny wynik filtra nie jest nowo utworzoną geometrią logiczną. Zachowaj oryginalne kształty, utwórz i sprawdź wymagane kontury w docelowym procesie ścieżek, a osobno zweryfikuj aplikację odbiorcy i wymagania produkcyjne.

## Źródła

1. [MDN: feComposite](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/feComposite) — Role wejść w przestrzeni obrazu, opisy operatorów i domyślna przestrzeń kolorów filtra.
2. [MDN: operator](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/operator) — Wartości operatorów kompozycji i osobny kontekst morfologii.
3. [MDN: filterUnits](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/filterUnits) — Układ współrzędnych obszaru filtra.
4. [MDN: feImage](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/feImage) — Wejście obrazu do potoku filtrów.
5. [W3C: Kompozycja Filter Effects](https://www.w3.org/TR/filter-effects-1/#feCompositeElement) — Definicje kompozycji premultiplikowanego koloru i alfa.

***

Zaczynasz od własnego rastrowego clipartu? [Utwórz edytowalny wzorzec SVG](https://perfectvector.com/pl/clipart-to-svg), sprawdź kontury i otwory, a potem zachowaj go podczas kontroli wybranej wizualnej kompozycji lub osobno utworzonego wyniku ścieżek w miejscu docelowym.

## Explore

- [Read the HTML article](https://perfectvector.com/pl/blog/svg-composite-artwork)
- [Trwale przytnij SVG bez ukrytych ścieżek](https://perfectvector.com/pl/blog/permanent-crop-svg.md)
- [Inkscape: Object to Path czy Stroke to Path?](https://perfectvector.com/pl/blog/inkscape-stroke-vs-object-to-path.md)
- [Product facts](https://perfectvector.com/product-facts.md)
- [FAQ](https://perfectvector.com/faq.md)
- [Pricing and credits](https://perfectvector.com/pricing.md)
