Pergunta

Eu tenho dois bitmaps, produzidos por diferentes variações de um algoritmo. Eu gostaria de criar um terceiro bitmap subtraindo uma da outra para mostrar as diferenças.

Como isso pode ser feito em .NET? Eu olhei sobre a classe Graphics e todas as suas opções, incluindo a classe ImageAttributes, e eu tenho um palpite que envolve a funcionalidade de matriz de cor ou mesas de remapeamento.

Alguém tem um link para um exemplo de código, ou pode me apontar na direção certa? Uma busca no Google não revela muito, a menos que meu google-fu está falhando comigo hoje.

Foi útil?

Solução

A verdadeira questão é, quais as diferenças que você quer mostrar? Se você só precisa para operar em valores de cor RGB, a melhor aposta na minha opinião é apenas de varredura através de ambos os bitmaps e comparar os valores de cor usando GetPixel e uso SetPixel para gerar o seu bitmap 'diferença'. Talvez você simplesmente quer subtrair os valores e utilizá-las como o novo valor da cor para o terceiro bitmap. Ou talvez você queira calcular a luminosidade e usar isso. Ainda melhor, se você tem três métricas para comparação, atribuir a cada um para o R G e componentes B da cor. Eu usei esta abordagem para colorização fractal antes.

Existem outras abordagens, mas com este que você está limitado apenas à sua imaginação. Pode não ser a abordagem mais rápida, mas não soa como o desempenho é necessário para este cenário.

Outras dicas

Confira este projeto. É um detector de movimento feito por Andrew Kirillov. Ele implementa um par de filtros para obter as diferenças entre duas imagens e usos que para calcular os movimentos. É muito bom feito e é fácil de modificar e usar em seu próprio aplicativo.

http://www.codeproject.com/KB/audio-video /Motion_Detection.aspx

Isto pode ser feito por PInvoking o função BitBlt API. Aqui está um código de exemplo:

http://www.codeproject.com/KB/GDI-plus /Bitblt_wrapper_class.aspx

O exemplo usa o código SRCCOPY raster op; para obter as diferenças entre dois bitmaps, você ao invés quer usar SRCPAINT ou algo (Google deve dar a lista de códigos).

GetPixel e SetPixel (na classe Bitmap) são incrivelmente lento. Usando LockBits será muito mais rápido, mas você ainda terá que escrever o seu próprio código.

Update: este é um link melhor:

http://www.pinvoke.net/default.aspx/gdi32.BitBlt

e inclui todas as operações possíveis ternário raster (SRCPAINT ou SRCAND são provavelmente o que você está procurando.).

Primeiro, defina subtrair ;-p O que você quer a resposta para olhar como?

A maneira mais desempenho de fazer isso é provavelmente LockBits - deve ser muito mais rápido do que muitas chamadas GetPixel, mas você vai precisar para decodificar o mesmo bytes. Fácil se é apenas algo como 32 bpp ARGB, mas complicado para alguns casos mais complexos.

Eu li em algum lugar que a linguagem utilizada na Adobe Pixel Bender é inspirado algo que a Microsoft fez uma vez. Não lembro onde li isso. Meu pensamento é que talvez que a Microsoft "algo" é envolvido em algo que um projeto .Net pode usar. Overkill por apenas subtraindo duas imagens, mas de qualquer maneira.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top