5.10. Operações bit a bit

As operações aritméticas da página anterior trabalham sobre os valores dos pixels – os brilhos inteiros ou as palavras de cor empacotadas. As operações bit a bit trabalham um nível abaixo, sobre os bits individuais dentro desses valores. Para imagens binárias, onde cada pixel é apenas um bit, as operações bit a bit são a aritmética natural.

5.10.1. A família bit a bit

A classe Image expõe o conjunto completo de operações bit a bit de duas entradas:

Cada uma opera por bit em cada byte dos buffers de ambas as imagens. Em uma imagem binária, onde cada byte contém oito pixels, a operação é executada em oito pixels por byte processado. Em uma imagem em escala de cinza ou colorida, ela é executada em cada bit de cada canal.

Três tabelas-verdade para as operações AND, OR e XOR lado a lado. Cada tabela tem quatro linhas para as combinações de entrada 0-0, 0-1, 1-0, 1-1 e colunas rotuladas A, B e resultado. Abaixo das tabelas-verdade, duas pequenas imagens binárias A e B são desenhadas como grades de células pretas e brancas, com o resultado do AND entre elas mostrado à direita como uma grade que mantém apenas as células que eram brancas em ambas.

Topo: as tabelas-verdade AND, OR e XOR – a semântica em nível de bit de cada operação. Base: duas imagens binárias A e B e o resultado de A.b_and(B), onde o resultado mantém apenas as posições que estavam ligadas em ambas as entradas.

5.10.2. Combinando máscaras

O uso mais comum dessas operações é combinar máscaras. Uma máscara é uma imagem binária que diz, posição por posição, se alguma condição é satisfeita. Duas máscaras que descrevem condições diferentes se combinam em uma única máscara que descreve uma condição composta por meio de uma das operações bit a bit:

b_and() produz uma máscara cujas posições estão ligadas apenas quando ambas as máscaras de entrada estavam ligadas naquela posição – o “e” natural de duas condições. Combinar uma máscara de primeiro plano com a saída de uma passagem de limiarização através de b_and restringe as correspondências do limiar ao primeiro plano.

b_or() produz uma máscara cujas posições estão ligadas sempre que qualquer uma das máscaras de entrada estava ligada – o “ou” natural. Fazer OR de duas saídas limiarizadas produz uma única máscara cobrindo qualquer coisa que correspondeu a qualquer uma das duas faixas de cor.

b_xor() produz uma máscara cujas posições estão ligadas sempre que exatamente uma máscara de entrada estava ligada. Útil para detectar posições onde duas máscaras discordam – as posições onde a saída do limiar mudou entre dois quadros, a diferença simétrica entre duas máscaras de referência, esse tipo de coisa.

As variantes negadas – b_nand(), b_nor(), b_xnor() – produzem o complemento de suas contrapartes não negadas. Elas são úteis quando a maneira natural de descrever uma condição é “nenhuma destas” ou “não ambas” – não é comum, mas vale saber que existem para que a negação não precise ser composta seguindo um AND com um invert() separado.

5.10.3. Bit a bit em imagens não binárias

As operações bit a bit também são executadas em imagens em escala de cinza e coloridas. Elas são mais úteis ali quando a imagem contém conteúdo semelhante a binário – um quadro em escala de cinza cujos pixels são todos 0 ou 255, um quadro RGB565 com apenas pixels totalmente pretos e totalmente brancos – onde AND, OR e XOR dão as mesmas combinações que dariam em uma imagem binária verdadeira. Para imagens que abrangem toda a faixa de valores, as operações aritméticas da página anterior costumam ser uma escolha melhor.