LSB-first within byte, row-major; same thresholds as app.js buildMonoBitmapFromImageData.
(rgba: bytes, w: int, h: int)
| 58 | |
| 59 | |
| 60 | def rgba_to_mono_xbm(rgba: bytes, w: int, h: int) -> bytes: |
| 61 | """LSB-first within byte, row-major; same thresholds as app.js buildMonoBitmapFromImageData.""" |
| 62 | alpha_threshold = 16 |
| 63 | luma_threshold = 0.35 |
| 64 | bytes_per_row = (w + 7) // 8 |
| 65 | buf = bytearray(bytes_per_row * h) |
| 66 | for y in range(h): |
| 67 | for x in range(w): |
| 68 | i = (y * w + x) * 4 |
| 69 | r, g, b, a = rgba[i], rgba[i + 1], rgba[i + 2], rgba[i + 3] |
| 70 | lum = (0.299 * r + 0.587 * g + 0.114 * b) / 255.0 |
| 71 | if a >= alpha_threshold and lum >= luma_threshold: |
| 72 | bi = y * bytes_per_row + (x >> 3) |
| 73 | buf[bi] |= 1 << (x & 7) |
| 74 | return bytes(buf) |
| 75 | |
| 76 | |
| 77 | def resolve_icon_file(static_root: Path, rel_file: str) -> Path: |