(imageData, colorCount)
| 746 | |
| 747 | // 复用existing的medianCutQuantization方法 |
| 748 | medianCutQuantization(imageData, colorCount) { |
| 749 | // 从main.js复制并修改的方法 |
| 750 | const pixels = []; |
| 751 | for (let i = 0; i < imageData.data.length; i += 4) { |
| 752 | pixels.push([ |
| 753 | imageData.data[i], |
| 754 | imageData.data[i + 1], |
| 755 | imageData.data[i + 2], |
| 756 | imageData.data[i + 3] |
| 757 | ]); |
| 758 | } |
| 759 | |
| 760 | let boxes = [new ColorBox(pixels)]; |
| 761 | |
| 762 | while (boxes.length < colorCount) { |
| 763 | let boxToSplit = boxes.reduce((a, b) => |
| 764 | a.largestRange > b.largestRange ? a : b |
| 765 | ); |
| 766 | |
| 767 | boxes = boxes.filter(box => box !== boxToSplit); |
| 768 | |
| 769 | const newBoxes = boxToSplit.split(); |
| 770 | if (newBoxes) { |
| 771 | boxes.push(...newBoxes); |
| 772 | } else { |
| 773 | break; |
| 774 | } |
| 775 | } |
| 776 | |
| 777 | const palette = boxes.map(box => box.getAverageColor()); |
| 778 | |
| 779 | for (let i = 0; i < imageData.data.length; i += 4) { |
| 780 | const pixel = [ |
| 781 | imageData.data[i], |
| 782 | imageData.data[i + 1], |
| 783 | imageData.data[i + 2], |
| 784 | imageData.data[i + 3] |
| 785 | ]; |
| 786 | |
| 787 | let minDistance = Infinity; |
| 788 | let closestColor = null; |
| 789 | |
| 790 | for (const color of palette) { |
| 791 | const distance = this.colorDistance(pixel, color); |
| 792 | if (distance < minDistance) { |
| 793 | minDistance = distance; |
| 794 | closestColor = color; |
| 795 | } |
| 796 | } |
| 797 | |
| 798 | imageData.data[i] = closestColor[0]; |
| 799 | imageData.data[i + 1] = closestColor[1]; |
| 800 | imageData.data[i + 2] = closestColor[2]; |
| 801 | imageData.data[i + 3] = closestColor[3]; |
| 802 | } |
| 803 | } |
| 804 | |
| 805 | colorDistance(color1, color2) { |
no test coverage detected