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

# SVG feComposite: เทียบภาพด้วย in, out และ xor

> เทียบอินพุตฟิลเตอร์ SVG ด้วย in, out และ xor ทดสอบลำดับกับอัลฟาบางส่วน และเก็บเส้นต้นฉบับเมื่อช่องที่เห็นไม่ใช่รูปทรงแก้ไขได้

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

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

SVG `feComposite` รวมอินพุตเรนเดอร์สองชุด สำหรับอินพุตทึบเต็ม `in` เก็บชุดแรกในส่วนทับกัน `out` เก็บนอกส่วนทับ และ `xor` รวมทั้งสองนอกส่วนทับร่วม คำสั่งเหล่านี้เปลี่ยนสีขณะเรนเดอร์ ไม่เขียนเส้นต้นฉบับใหม่เป็นจุดตัดหรือผลต่างที่แก้ไขได้

ความต่างสำคัญเมื่อส่วนทับดูเป็นช่อง แต่งานส่งต้องการเส้นขอบจริง ตัวอย่างด้านล่างเทียบรูปไม่สมมาตรต้นฉบับสองรูป สลับอินพุต และตรวจความโปร่งใสบางส่วน เก็บภาพต้นฉบับคู่ผลใส่ฟิลเตอร์

## ตั้งชื่อสองอินพุตก่อนเลือกตัวดำเนินการ

[เอกสาร feComposite ของ MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/feComposite) อธิบายการทำงานทีละพิกเซลในพื้นที่ภาพ `in` ระบุอินพุตแรก `in2` ระบุที่สอง ตั้งชื่อผลระหว่างทางชัดเจนเพื่อไม่ให้แก้สายฟิลเตอร์แล้วเปลี่ยนตัวถูกดำเนินการเงียบ ๆ

สำหรับพื้นที่ทึบด้านใน สามคำสั่งเทียบง่าย:

| คำสั่ง | อินพุตแรก A ที่สอง B     | ผลเมื่อสลับอินพุต        |
| ------ | ------------------------ | ------------------------ |
| `in`   | สี A ในส่วนทับ           | ส่วนทับใช้สี B แทน       |
| `out`  | สี A นอก B               | สี B นอก A เป็นอีกบริเวณ |
| `xor`  | ทั้งสองนอกส่วนทับทึบร่วม | เหลือบริเวณไม่ทับเดิม    |

แอตทริบิวต์ `operator` เดียวกันยังปรากฏในองค์ประกอบฟิลเตอร์อื่นด้วยค่าต่างกัน ระบุบริบทประกอบภาพให้ชัด [เอกสาร operator ของ MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/operator) แยกจากคำสั่ง morphology

**เปลี่ยนสีที่เห็น**

![การเทียบแนวคิดภาพสีทับกันกับภาพประกอบที่ส่วนทับไม่ระบาย](https://perfectvector.com/blog/svg-composite-artwork/overlap-and-paint.webp)

*ภาพอธิบาย: อินพุตทับกันอาจเหลือพื้นที่ไม่ระบาย เงารูปตกแต่งและลูกศรเป็นแนวคิด คำสั่งจริง ตัวอย่างอัลฟา และเส้นไม่เปลี่ยนด้านล่างมาจากไฟล์ทดสอบเบราว์เซอร์ต้นฉบับที่รันจริง*

## จัดภาพที่สองให้ตรงอย่างชัดเจน

ตัวถูกดำเนินการแรก A เป็นบล็อกขั้นบันไดสีเขียวน้ำทะเล B เป็นว่าวเอียงสีเหลืองดิน ทั้งคู่ใช้ viewBox `0 0 240 160` B ยื่นเกินกรอบเฉพาะที่ของ A การใช้ขอบเขต A เป็นพื้นที่ฟิลเตอร์จึงเป็นสมมติฐานตั้งต้นไม่ดี

ฟิลเตอร์ใช้ `filterUnits="userSpaceOnUse"` กับพื้นที่ชัดเจน `x=0`, `y=0`, `width=240`, `height=160` [เอกสาร filterUnits ของ MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/filterUnits) อธิบายตัวเลือกพิกัด เราตั้ง `primitiveUnits="userSpaceOnUse"` และให้อินพุตที่สองพิกัดเต็มกรอบเดียวกันด้วย

B เป็น SVG data URL ครบในตัวที่ส่งผ่าน `feImage` พร้อมชื่อผล `operandB` สิ่งนี้นำเข้าเป็นภาพของฟิลเตอร์ ไม่ได้แทรกเส้น B เป็นลูกโดยตรงใหม่ของภาพรับฟิลเตอร์ [เอกสาร feImage ของ MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/feImage) อธิบายอินพุตภาพ

ฟิลเตอร์เลือก `sRGB` ชัดเจน ค่าเริ่มต้นขององค์ประกอบเหล่านี้คือ `linearRGB` ตามเอกสาร feComposite ทั้งค่าเริ่มต้นและชื่อคำสั่งไม่ให้การแก้เส้น

## รันการเทียบต้นฉบับครบชุด

บันทึกเป็น `starter.html` และให้บริการโฟลเดอร์ผ่าน HTTP ในเครื่อง เช่น `python3 -m http.server 8766 --bind 127.0.0.1` เปิด `http://127.0.0.1:8766/starter.html` ใช้พอร์ตว่างอื่นหากจำเป็น

หน้าสร้างต้นฉบับสองชุดกับกรณีฟิลเตอร์เจ็ดชุดที่แต่ละขนาดชัดเจนสองขนาด ID ฟิลเตอร์แต่ละตัวรวมกรณีและความกว้าง เพื่อให้หลาย SVG inline ในเอกสารเดียวอ้างอิงไม่ซ้ำ ลิงก์ Save SVG แต่ละอันเก็บฟิลเตอร์ครบในตัวกับอินพุต 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>
```

โค้ดเก็บเส้น A โดยตรงเดิมแม้สลับอินพุต เช่น `b-in-a` เปลี่ยน `feComposite` เป็น `in="operandB"` และ `in2="SourceGraphic"` ไม่ได้แทนองค์ประกอบต้นทางที่ใส่ฟิลเตอร์ด้วย B จึงเห็นลำดับโดยไม่เปลี่ยนรูปทรง A พื้นฐาน

การตรวจพิกเซลอ่าน canvas ที่วาดจาก SVG สร้างแต่ละชุด งานดาวน์โหลดยังเป็น SVG ใส่ฟิลเตอร์ ไม่ใช่เส้นบูลีนใหม่หรือการแปลง PerfectVector

## เทียบสีกับรูปทรงแยก

เรารันหน้านี้ตรง ๆ ใน Chrome หนึ่งสภาพแวดล้อมที่ `120 × 80` และ `240 × 160` บันทึก SVG ทั้ง 18 และเปิดเป็นภาพใหม่ในเบราว์เซอร์เดิม ขนาดแสดงเป็นอินพุตชัดเจน ไม่ใช่ข้อกล่าวอ้างอุปกรณ์จริงสองเครื่อง

จุดตัวอย่างด้านในสามจุดใช้ระบบพิกัดเดิม ได้แก่ A เท่านั้น `(40,40)` B เท่านั้น `(200,84)` และส่วนทับ `(120,84)` พบอัลฟาต่อไปนี้ทั้งสองขนาดเมื่ออินพุตทึบ:

| อินพุตและคำสั่ง | อัลฟาเฉพาะ A | อัลฟาเฉพาะ B | อัลฟาส่วนทับ |
| --------------- | ------------ | ------------ | ------------ |
| 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            |

แถว `in` มีส่วนทับทึบร่วมแต่สีต่าง A ก่อนเป็นเขียวน้ำทะเล `(23,107,91,255)` B ก่อนเป็นเหลืองดิน `(212,165,58,255)` จุดนอก `(230,150)` โปร่งใสตลอด นี่เป็นพิกเซลในที่เลือก ไม่ใช่ทดสอบครอบคลุมขอบหรือความเข้ากันได้ทั้งหมด

ทุกไฟล์ฟิลเตอร์ยังมีสตริง `d` ต้นฉบับ A ตรงค่าและ SHA-256 ตรงกัน ค่า `getBBox()` รูปทรงเฉพาะที่ยังเป็น `x=24`, `y=24`, `width=168`, `height=112` กรอบนี้อธิบายเส้นต้นฉบับ ไม่ใช่กรอบพิกเซลฟิลเตอร์ที่เห็น เส้น B เข้ารหัสก็ไม่เปลี่ยน ผลฟิลเตอร์จึงดูต่างได้ขณะที่สองเส้นขอบที่สร้างยังอยู่ครบ

ต้นฉบับบันทึกมีเส้นโดยตรงหนึ่งเส้นและไม่มีภาพฟิลเตอร์ ไฟล์ฟิลเตอร์แต่ละชุดมี A โดยตรงหนึ่งเส้นบวก `feImage` หนึ่งตัวที่บรรจุ SVG หนึ่งเส้นของ B แยก ไม่มีองค์ประกอบแรสเตอร์ `image` ปกติถูกเพิ่ม การทำงานพื้นที่ภาพเรนเดอร์กับอินพุตเวกเตอร์อยู่ร่วมกันได้ รายการต้นฉบับอย่างเดียวไม่ได้แปลว่าผลกลายเป็นรูปทรงรวมแก้ไขได้

## ความทึบบางส่วนเปลี่ยนความหมายของช่อง

กรณีสุดท้ายทำ B ทึบครึ่งหนึ่งโดยคง A ทึบ แล้วใช้ A `out` B ส่วนทับไม่ได้ว่าง ทั้งสองขนาดมี RGBA `(22,106,90,127)` เป็นเขียวน้ำทะเลโปร่งใสบางส่วนพร้อมการปัดจากกระบวนการเรนเดอร์/อ่าน

สำหรับ `out` อัลฟาผลคืออัลฟาแรกคูณหนึ่งลบอัลฟาที่สอง สำหรับ `in` คือผลคูณทั้งคู่ [นิยามการประกอบ Filter Effects](https://www.w3.org/TR/filter-effects-1/#feCompositeElement) นิยามผ่านสี premultiplied และอัลฟา B ทึบลบสี A ส่วนทับได้ ส่วน B โปร่งบางส่วนเหลือสีบางส่วน

ตรวจผลบนฉากหลังจริง บริเวณอ่อนบนขาวอาจเป็นสีโปร่งแสง ไม่ใช่ช่องโปร่งใสเต็ม พิกเซลขอบลบรอยหยักก็ต้องตรวจด้วยตา จุดด้านในไม่ได้รับปากว่าทุกพิกเซลขอบมีอัลฟาศูนย์ สำหรับงานปรับความทึบแยก ดู[คู่มือเกณฑ์อัลฟา SVG](https://perfectvector.com/th/blog/svg-alpha-threshold)

## ส่งผลฟิลเตอร์หรือสร้างเส้นขอบจริง

เก็บฟิลเตอร์นี้เมื่อตัวเรนเดอร์ผู้รับควรทำภาพประกอบซ้ำ รักษาไฟล์ A และ B เดิมและตรวจ SVG ฟิลเตอร์ที่เปิดใหม่ในปลายทางจริง การเปิดสำเร็จในเบราว์เซอร์เราไม่รับรองตัวเรนเดอร์หรือเครื่องผลิตอื่น

หากส่งต้องการเส้นรวมที่เลือกได้หรือช่องพร้อมตัด ให้ทำและตรวจการแก้เส้นจริงหรือบูลีนในขั้นตอนเป้าหมาย สีที่เห็นเปลี่ยนที่นี่ไม่สร้างรูปทรงนั้น [คู่มือ clipPath กับ mask](https://perfectvector.com/th/blog/svg-clippath-vs-mask) แยกเรื่องการมองเห็นที่เกี่ยวข้อง [คู่มือแยกกลุ่ม SVG](https://perfectvector.com/th/blog/svg-wont-ungroup) ช่วยเมื่อภาพที่แสดงไม่ใช่วัตถุแก้ไขได้ที่คาด

หากคลิปอาร์ตมีเพียงพิกเซลและต้องการรูปต้นทางแก้ไขได้ ให้[เตรียมคลิปอาร์ต SVG ด้วย PerfectVector](https://perfectvector.com/th/clipart-to-svg) ตรวจเส้นขอบและช่อง แล้วเก็บต้นฉบับหลัก ใช้และตรวจฟิลเตอร์หรือคำสั่งเส้นที่ตั้งใจแยก การแปลงเวกเตอร์ไม่เปลี่ยนส่วนทับที่เห็นจากฟิลเตอร์นี้เป็นเส้นผลิตที่ตรวจแล้ว

## คำถามที่พบบ่อย

**feComposite out ลบรูปทรงเส้นส่วนทับหรือไม่?**
ไม่ มันเปลี่ยนสีเรนเดอร์โดยใช้อัลฟาอินพุตสอง ในไฟล์ฟิลเตอร์ของเรา ข้อมูลเส้น A เดิมและขอบเขตรูปทรงเฉพาะที่ไม่เปลี่ยน แม้สีส่วนทับโปร่งใส

**ทำไมสลับ in กับ in2 แล้วผลเปลี่ยน?**
มันระบุอินพุตแรกและสอง In เก็บสีแรกในความทึบของสอง out เก็บแรกภายนอก กรณี in สลับของเรามีส่วนทับทึบร่วมแต่คนละสี ส่วน out สลับเก็บคนละบริเวณ

**xor ทำส่วนทับว่างเต็มเสมอหรือไม่?**
ส่วนทับด้านในทึบเต็มว่างในกรณี xor ของเรา อัลฟาบางส่วนและขอบลบรอยหยักต้องตรวจเอง แผนภาพเซตของรูปทึบไม่อธิบายทุกพิกเซลโปร่งแสง

**ส่งช่องฟิลเตอร์เป็นเส้นตัดแก้ไขได้โดยตรงได้หรือไม่?**
ผลฟิลเตอร์ที่เห็นไม่ใช่รูปทรงบูลีนสร้างใหม่ เก็บรูปเดิม สร้างและตรวจเส้นที่ต้องใช้ในขั้นเส้นเป้าหมาย แล้วตรวจแอปผู้รับกับข้อกำหนดผลิตแยก

## แหล่งข้อมูล

1. [MDN: feComposite](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/feComposite) — บทบาทอินพุตพื้นที่ภาพ คำสั่ง และปริภูมิสีฟิลเตอร์เริ่มต้น
2. [MDN: operator](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/operator) — ค่าคำสั่งประกอบและบริบท morphology แยก
3. [MDN: filterUnits](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/filterUnits) — ระบบพิกัดพื้นที่ฟิลเตอร์
4. [MDN: feImage](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/feImage) — อินพุตภาพในสายฟิลเตอร์
5. [W3C: การประกอบ Filter Effects](https://www.w3.org/TR/filter-effects-1/#feCompositeElement) — นิยามประกอบสี premultiplied กับอัลฟา

***

เริ่มจากคลิปอาร์ตแรสเตอร์ของคุณหรือไม่? [สร้างต้นฉบับ SVG แก้ไขได้](https://perfectvector.com/th/clipart-to-svg) ตรวจเส้นขอบและช่อง แล้วเก็บต้นฉบับขณะตรวจภาพประกอบที่เลือกหรือผลเส้นที่สร้างแยกในปลายทาง

## Explore

- [Read the HTML article](https://perfectvector.com/th/blog/svg-composite-artwork)
- [ครอป SVG ถาวรโดยไม่เหลือพาธที่ซ่อนอยู่](https://perfectvector.com/th/blog/permanent-crop-svg.md)
- [Inkscape: Object to Path กับ Stroke to Path ต่างอย่างไร](https://perfectvector.com/th/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)
