Editando Pixels - JavaScript

O JavaScript oferece funcionalidades integradas para editar imagens e definir valores específicos de pixels em um canvas. Em particular, é possível modificar as cores dos pixels e sua transparência utilizando métodos como getImageData(), putImageData() e createImageData().

Método getImageData()

O método getImageData() permite extrair uma parte da imagem contida no canvas. Ele é definido da seguinte maneira:

getImageData(sx, sy, sw, sh);

Aqui, sx e sy são as coordenadas do canto superior esquerdo da área que será extraída do canvas, enquanto sw e sh representam, respectivamente, a largura e a altura dessa área.

Os dados extraídos dessa área específica são armazenados em um objeto ImageData, que pode ser utilizado para manipular pixels.

Exemplo de uso:

const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
                    
const img = new Image();
img.src = "forest.png";
img.onload = function() {
    context.drawImage(img, 0, 0);
    const imageData = context.getImageData(0,0, 100, 100);
};

Todas as informações da imagem no objeto ImageData são armazenadas em um array chamado data. Cada pixel no canvas é caracterizado por quatro componentes no formato RGBA: vermelho, verde, azul e alfa (transparência). Cada componente pode ter um valor entre 0 e 255. Para obter os valores de cor do primeiro pixel no ImageData, basta acessar quatro valores consecutivos no array data:

const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
                    
const img = new Image();
img.src = "dubi.png";
img.onload = function() {
                    
    context.drawImage(img, 0, 0);
    const imageData = context.getImageData(0,0, 100, 100);
    const red = imageData.data[0];  // componente vermelha
    const green = imageData.data[1];    // componente verde
    const blue = imageData.data[2]; // componente azul
    const alpha = imageData.data[3];    // componente alfa
};

Nesse caso, estamos obtendo as informações do primeiro pixel, localizado no canto superior esquerdo, com coordenadas x=0 e y=0.

Para obter as informações do segundo pixel, com coordenadas x=1 e y=0, deve-se acessar os quatro valores subsequentes no array data:

const red = imageData.data[4];  // componente vermelha
const green = imageData.data[5];    // componente verde
const blue = imageData.data[6]; // componente azul
const alpha = imageData.data[7];    // componente alfa

Assim, é possível obter informações de todos os pixels.

Método putImageData()

O método putImageData() insere novos dados no canvas. Ele pode ser utilizado de duas formas:

putImageData(imageData, dx, dy)
putImageData(imageData, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)

Os parâmetros dx e dy indicam as coordenadas do canto superior esquerdo do retângulo representado por imageData, que será colocado no canvas.

Os parâmetros adicionais dirtyX e dirtyY especificam as coordenadas do canto superior esquerdo da área retangular a ser extraída da imagem. Já dirtyWidth e dirtyHeight determinam a largura e a altura dessa área.

Vamos usar os métodos getImageData() e putImageData() para transformar uma imagem:

<!DOCTYPE html>
<html>
    <head>
    <meta charset="utf-8" />
    <title>Programício</title>
    </head>
    <body>
    <canvas id="canvas" width="1000" height="300"></canvas>
    <script>
        const canvas = document.getElementById('canvas');
        const context = canvas.getContext('2d');

        const img = new Image();
        img.src = 'forest.png';
        img.onload = function () {
        context.drawImage(img, 0, 0);
        const imageData = context.getImageData(0, 0, img.width, img.height);
        let red, green, blue, grayscale;

        for (let i = 0; i < imageData.data.length; i += 4) {
            red = imageData.data[i]; // componente vermelha
            green = imageData.data[i + 1]; // componente verde
            blue = imageData.data[i + 2]; // componente azul
            grayscale = red * 0.3 + green * 0.59 + blue * 0.11; // conversão para escala de cinza
            imageData.data[i] = grayscale; // ajusta cor para escala de cinza
            imageData.data[i + 1] = grayscale;
            imageData.data[i + 2] = grayscale;
        }
        context.putImageData(imageData, img.width + 10, 0);
        };
    </script>
    </body>
</html>
Transformação de imagem em em tons de cinza no canvas em JavaScript

A parte central do código acima é o loop que converte a imagem em tons de cinza:

let red, green, blue, grayscale;
                  
for (let i = 0; i < imageData.data.length; i += 4) {
    red = imageData.data[i]; // componente vermelha
    green = imageData.data[i + 1];  // componente verde
    blue = imageData.data[i + 2];   // componente azul
    grayscale = red * 0.3 + green * 0.59 + blue * 0.11; // conversão para escala de cinza
    imageData.data[i] = grayscale;  // ajusta cor para escala de cinza
    imageData.data[i + 1] = grayscale;
    imageData.data[i + 2] = grayscale;
}  

Nesse loop, percorremos todo o array imageData.data, processando quatro elementos de cada vez, representando um pixel. Como a componente de transparência (alfa) não nos interessa nesse caso, consideramos apenas as três componentes de cor.

Primeiro, obtemos as componentes RGB. Em seguida, aplicamos uma fórmula matemática para converter os valores RGB para tons de cinza. Finalmente, configuramos o valor em tons de cinza para cada componente do pixel.

Questões de Segurança

Se você tentar executar o código acima em um arquivo HTML localmente, abrindo-o diretamente no navegador Google Chrome, o navegador pode não exibir a imagem convertida para tons de cinza devido às suas políticas de segurança. No entanto, em outros navegadores como Firefox ou Microsoft Edge, o código pode funcionar normalmente. Isso ocorre porque o Google Chrome impede manipulações de imagens entre domínios diferentes. Quando um arquivo é aberto via protocolo file://, o navegador considera o usuário e a página da web como pertencentes a domínios diferentes.

Para evitar esse problema, a página da web deve ser hospedada em um servidor web e acessada via protocolo http. Assim, o usuário e o site estarão no mesmo domínio, e a manipulação das imagens será permitida. Para testes locais, você pode utilizar um servidor web local, ou ajustar as configurações de segurança do Google Chrome.

Método createImageData()

O método createImageData() cria um novo objeto ImageData, que pode ser utilizado no canvas. Este método possui duas formas:

createImageData(width, height);
createImageData(imagedata);

A primeira forma aceita parâmetros width e height, que determinam, respectivamente, a largura e a altura do novo objeto ImageData.

A segunda forma aceita outro objeto ImageData como parâmetro, a partir do qual um novo objeto ImageData será criado.

Exemplo de uso:

<!DOCTYPE html>
<html>
    <head>
    <meta charset="utf-8" />
    <title>Programício</title>
    </head>
    <body>
    <canvas id="canvas" width="1000" height="300"></canvas>
    <script>
        const canvas = document.getElementById('canvas');
        const context = canvas.getContext('2d');

        const img = new Image();
        img.src = 'forest.png';
        img.onload = function () {
        context.drawImage(img, 0, 0);
        const imageData = context.getImageData(0, 0, img.width, img.height);
        const newImageData = context.createImageData(imageData);

        for (let i = 0; i < newImageData.data.length; i++) {
            newImageData.data[i] = imageData.data[i];
            // Se for a componente alfa
            if ((i + 1) % 4 === 0) {
            newImageData.data[i] = 120;
            }
        }
        context.putImageData(newImageData, img.width + 10, 0);
        };
    </script>
    </body>
</html>

Nesse exemplo, criamos um novo objeto newImageData e copiamos para ele todos os dados do objeto imageData atual, que representa a imagem no canvas. Durante a cópia, definimos o valor da componente alfa para 120, tornando o pixel semitransparente.

Efeitos de imagem no canvas em JavaScript
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com