Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
ded5ca94eThis file is pinned to the selected release. Download the original to open it in your design tool.
import type { CameraFrame } from './camera.js'
export type MosaicBlock = {
x: number
y: number
width: number
height: number
color: number
}
export type MosaicOptions = {
width: number
height: number
blockSize: number
}
export function rgb565LeToPiuColor(buffer: ArrayBuffer, byteOffset: number): number {
const view = new Uint8Array(buffer)
const pixel = view[byteOffset] | (view[byteOffset + 1] << 8)
const red5 = (pixel >> 11) & 0x1f
const green6 = (pixel >> 5) & 0x3f
const blue5 = pixel & 0x1f
const red = (red5 << 3) | (red5 >> 2)
const green = (green6 << 2) | (green6 >> 4)
const blue = (blue5 << 3) | (blue5 >> 2)
return (red << 16) | (green << 8) | blue
}
function clampSampleCoordinate(value: number, maxExclusive: number): number {
const coordinate = value | 0
if (coordinate < 0) return 0
if (coordinate >= maxExclusive) return maxExclusive - 1
return coordinate
}
export function sampleRgb565LeMosaic(frame: CameraFrame, options: MosaicOptions): MosaicBlock[] {
if (frame.imageType !== 'rgb565le' || frame.width <= 0 || frame.height <= 0) {
return []
}
const blockSize = Math.max(1, options.blockSize | 0)
const targetWidth = Math.max(1, options.width | 0)
const targetHeight = Math.max(1, options.height | 0)
const blocks: MosaicBlock[] = []
for (let y = 0; y < targetHeight; y += blockSize) {
const height = Math.min(blockSize, targetHeight - y)
const sampleY = clampSampleCoordinate(((y + height / 2) * frame.height) / targetHeight, frame.height)
for (let x = 0; x < targetWidth; x += blockSize) {
const width = Math.min(blockSize, targetWidth - x)
const sampleX = clampSampleCoordinate(((x + width / 2) * frame.width) / targetWidth, frame.width)
const byteOffset = (sampleY * frame.width + sampleX) * 2
blocks.push({
x,
y,
width,
height,
color: rgb565LeToPiuColor(frame.buffer, byteOffset),
})
}
}
return blocks
}