* Apply a bi-level (threshold) effect to an image. * * OOXML ` ` converts the image to black and white. * Each pixel's luminance is compared to the threshold (0–100000 = 0–100%). * Pixels above become white, pixels below become black. Alpha is preserved.
(biLevel: SafeXmlNode, img: HTMLImageElement)
| 618 | * Pixels above become white, pixels below become black. Alpha is preserved. |
| 619 | */ |
| 620 | function applyBiLevelEffect(biLevel: SafeXmlNode, img: HTMLImageElement): void { |
| 621 | const thresh = (biLevel.numAttr('thresh') ?? 50000) / 100000 // 0–1 |
| 622 | |
| 623 | const apply = () => { |
| 624 | const w = img.naturalWidth |
| 625 | const h = img.naturalHeight |
| 626 | if (!w || !h) return |
| 627 | |
| 628 | const canvas = document.createElement('canvas') |
| 629 | canvas.width = w |
| 630 | canvas.height = h |
| 631 | const c = canvas.getContext('2d') |
| 632 | if (!c) return |
| 633 | |
| 634 | c.drawImage(img, 0, 0) |
| 635 | const imageData = c.getImageData(0, 0, w, h) |
| 636 | const data = imageData.data |
| 637 | |
| 638 | for (let i = 0; i < data.length; i += 4) { |
| 639 | const gray = (0.2126 * data[i] + 0.7152 * data[i + 1] + 0.0722 * data[i + 2]) / 255 |
| 640 | const val = gray >= thresh ? 255 : 0 |
| 641 | data[i] = val |
| 642 | data[i + 1] = val |
| 643 | data[i + 2] = val |
| 644 | // Alpha preserved |
| 645 | } |
| 646 | |
| 647 | c.putImageData(imageData, 0, 0) |
| 648 | img.src = canvas.toDataURL() |
| 649 | } |
| 650 | |
| 651 | if (img.complete && img.naturalWidth) { |
| 652 | apply() |
| 653 | } else { |
| 654 | img.addEventListener('load', apply, { once: true }) |
| 655 | } |
| 656 | } |
no test coverage detected