Created
May 12, 2023 05:57
-
-
Save guiseek/570fc5ca90a217bb307b3af100efc992 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import './style.scss' | |
const video = document.querySelector('video') as HTMLVideoElement; | |
const canvas = document.querySelector('canvas') as HTMLCanvasElement; | |
const ctx = canvas.getContext('2d', { willReadFrequently: true })!; | |
// Configuração da tela de fundo | |
const BACKGROUND_COLOR = [6, 6, 6]; // fundo verde | |
const TOLERANCE = 80; // tolerância de cor | |
const OPACITY = 0.7; // opacidade do sujeito | |
const MAX_ITERATIONS = 1000000; // número máximo de iterações para preencher o fundo | |
const PIXEL_STACK_LIMIT = 100000; // limite de pilha de pixel para preencher o fundo | |
// Iniciar a reprodução do vídeo | |
video.onplay = () => { | |
canvas.width = video.videoWidth | |
canvas.height = video.videoHeight | |
} | |
// video.play(); | |
// Desenhar a imagem na tela a cada quadro | |
function drawFrame() { | |
// desenhar o quadro atual do vídeo no canvas | |
ctx.drawImage(video, 0, 0, canvas.width, canvas.height); | |
// obter os pixels da imagem | |
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); | |
const pixels = imageData.data; | |
// percorrer os pixels da imagem | |
const stack = [[0, 0]]; // pilha de pixel para preencher o fundo | |
const visited = new Set(); // pixels já visitados | |
while (stack.length > 0) { | |
// obter o próximo pixel da pilha | |
const [x, y] = stack.pop() ?? []; | |
const index = (y * canvas.width + x) * 4; | |
// verificar se o pixel já foi visitado | |
if (visited.has(index)) { | |
continue; | |
} | |
visited.add(index); | |
// verificar se o pixel está próximo o suficiente da cor de fundo | |
const distance = Math.sqrt( | |
Math.pow(pixels[index] - BACKGROUND_COLOR[0], 2) + | |
Math.pow(pixels[index + 1] - BACKGROUND_COLOR[1], 2) + | |
Math.pow(pixels[index + 2] - BACKGROUND_COLOR[2], 2) | |
); | |
if (distance <= TOLERANCE) { | |
// preencher o pixel com a cor de fundo | |
pixels[index + 3] = OPACITY * 255; | |
// empilhar pixels vizinhos | |
if (stack.length < PIXEL_STACK_LIMIT) { | |
if (x > 0) { | |
stack.push([x - 1, y]); | |
} | |
if (x < canvas.width - 1) { | |
stack.push([x + 1, y]); | |
} | |
if (y > 0) { | |
stack.push([x, y - 1]); | |
} | |
if (y < canvas.height - 1) { | |
stack.push([x, y + 1]); | |
} | |
} | |
// verificar se atingimos o número máximo de iterações | |
if (visited.size >= MAX_ITERATIONS) { | |
break; | |
} | |
} | |
} | |
// desenhar a imagem atualizada no canvas | |
ctx.putImageData(imageData, 0, 0); | |
// chamar esta função novamente na próxima animação de quadro | |
// requestAnimationFrame(drawFrame); | |
video.requestVideoFrameCallback(drawFrame) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment