| import type { PixelData } from "./types.js"; |
|
|
| export function renderBraille(pixels: PixelData): string { |
| const { data, info } = pixels; |
| const { width, height, channels } = info; |
|
|
| let result = ""; |
| for (let y = 0; y < height - 3; y += 4) { |
| for (let x = 0; x < width - 1; x += 2) { |
| const dot1Index = (y * width + x) * channels; |
| const dot2Index = ((y + 1) * width + x) * channels; |
| const dot3Index = ((y + 2) * width + x) * channels; |
| const dot4Index = (y * width + x + 1) * channels; |
| const dot5Index = ((y + 1) * width + x + 1) * channels; |
| const dot6Index = ((y + 2) * width + x + 1) * channels; |
| const dot7Index = ((y + 3) * width + x) * channels; |
| const dot8Index = ((y + 3) * width + x + 1) * channels; |
|
|
| const getRgba = (index: number) => { |
| const r = data[index] as number; |
| const g = data[index + 1] as number; |
| const b = data[index + 2] as number; |
| const a = channels === 4 ? (data[index + 3] as number) : 1; |
| return { r, g, b, a }; |
| }; |
|
|
| const dot1 = rgbaToBlackOrWhite(getRgba(dot1Index)); |
| const dot2 = rgbaToBlackOrWhite(getRgba(dot2Index)); |
| const dot3 = rgbaToBlackOrWhite(getRgba(dot3Index)); |
| const dot4 = rgbaToBlackOrWhite(getRgba(dot4Index)); |
| const dot5 = rgbaToBlackOrWhite(getRgba(dot5Index)); |
| const dot6 = rgbaToBlackOrWhite(getRgba(dot6Index)); |
| const dot7 = rgbaToBlackOrWhite(getRgba(dot7Index)); |
| const dot8 = rgbaToBlackOrWhite(getRgba(dot8Index)); |
|
|
| const brailleChar = String.fromCharCode( |
| 0x2800 + |
| (dot8 << 7) + |
| (dot7 << 6) + |
| (dot6 << 5) + |
| (dot5 << 4) + |
| (dot4 << 3) + |
| (dot3 << 2) + |
| (dot2 << 1) + |
| dot1, |
| ); |
| result += brailleChar; |
| } |
| result += "\n"; |
| } |
|
|
| return result.slice(0, -1); |
| } |
|
|
| function rgbaToBlackOrWhite({ |
| r, |
| g, |
| b, |
| a, |
| }: { |
| r: number; |
| g: number; |
| b: number; |
| a: number; |
| }) { |
| const alpha = a / 255; |
| const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b; |
| const alphaAdjustedLuminance = luminance * alpha + 255 * (1 - alpha); |
|
|
| if (alphaAdjustedLuminance > 128) { |
| return 1; |
| } |
| return 0; |
| } |
|
|