2008-12-29 7 views
6

Ich habe zwei Bitmaps, die durch verschiedene Variationen eines Algorithmus erzeugt werden. Ich möchte ein drittes Bitmap erstellen, indem ich eins von dem anderen abziehe, um die Unterschiede zu zeigen.Wie wird in C# /. NET eine Bitmap von einer anderen subtrahiert?

Wie kann dies in .NET getan werden? Ich habe über die Graphics-Klasse und alle ihre Optionen, einschließlich der ImageAttributes-Klasse, und ich habe eine Ahnung, es betrifft die Farbmatrix oder Remap-Tabellen-Funktionalität.

Hat jemand einen Link zu einem Beispielcode oder kann er mir in die richtige Richtung zeigen? Eine Google-Suche verraten nicht viel, wenn mein Google-Fu mich heute nicht versagt.

Antwort

7

Die eigentliche Frage ist, welche Unterschiede möchten Sie zeigen? Wenn Sie nur mit RGB-Farbwerten arbeiten müssen, ist es meiner Meinung nach am besten, einfach beide Bitmaps durchzugehen und die Farbwerte mit GetPixel zu vergleichen und SetPixel zu verwenden, um Ihre "Differenz" -Bitmap zu erzeugen. Vielleicht möchten Sie einfach die Werte subtrahieren und diese als neuen Farbwert für die dritte Bitmap verwenden. Oder vielleicht möchten Sie die Leuchtkraft berechnen und verwenden. Noch besser, wenn Sie drei Metriken zum Vergleich haben, ordnen Sie jede den R G- und B-Komponenten der Farbe zu. Ich habe diesen Ansatz für die fraktale Kolorierung verwendet.

Es gibt andere Ansätze, aber mit diesem sind Sie nur auf Ihre Phantasie beschränkt. Es ist vielleicht nicht der schnellste Ansatz, aber es klingt nicht wie Leistung für dieses Szenario erforderlich ist.

+0

Sie haben Recht, Leistung ist nicht die Nr. 1 Ziel hier, und je mehr ich darüber nachdenke, es klingt, als müsste ich den Code selbst schreiben. Ich dachte zuerst an einen magischen invert-image2-add-to-image1-Algorithmus, aber wie würde es mit negativen Ergebnissen umgehen ... ok, zurück zur Arbeit dann :) –

+0

Wenn Sie die Leistung benötigen, denken Sie daran, dass Sie verwenden können die LockBits-Methode des Bitmap-Objekts, um ein Bytearray der rohen Pixelwerte abzurufen, mit denen Sie arbeiten können. Neigt dazu, viel schneller zu sein als GetPixel und SetPixel. – driis

3

Schauen Sie sich dieses Projekt an. Es ist ein Bewegungsmelder von Andrew Kirillov gemacht. Er implementiert ein paar Filter, um die Unterschiede zwischen zwei Bildern zu erhalten und verwendet diese, um Bewegungen zu berechnen. Es ist wirklich nett gemacht und es ist leicht zu modifizieren und in Ihrer eigenen Anwendung zu verwenden.

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

+0

das ist ein wirklich schönes Beispiel –

1

Zunächst definieren subtrahieren ;-P Was wollen Sie die Antwort aussehen?

Die Performance Art und Weise, dies zu tun ist wahrscheinlich LockBits - es sollte viel schneller als viele GetPixel Anrufe sein, aber Sie werden die Bytes selbst entschlüsseln müssen. Einfach, wenn es nur etwas wie 32bpp ARGB ist, aber schwierig für einige komplexere Fälle.

0

Ich habe irgendwo gelesen, dass die in Adobe Pixel Bender verwendete Sprache von etwas inspiriert ist, das Microsoft einmal getan hat. Erinnere dich nicht, wo ich es gelesen habe. Ich denke, dass Microsoft "etwas" in etwas eingewickelt ist, das ein .Net-Projekt nutzen kann. Overkill für nur zwei Bilder abziehen, aber wie auch immer.

2

Dies kann durch PInvozieren der API-Funktion BitBlt erfolgen. Hier ist ein Beispielcode:

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

Das Beispiel verwendet die SRCCOPY Rasteroperationscode; Um die Unterschiede zwischen zwei Bitmaps zu erhalten, sollten Sie stattdessen SRCPAINT oder etwas verwenden (GOOGLE sollte die Liste der Codes angeben).

GetPixel und SetPixel (auf der Bitmap-Klasse) sind unglaublich langsam. Die Verwendung von LockBits wird viel schneller sein, aber Sie müssen immer noch Ihren eigenen Code schreiben.

Update: dies ist eine bessere Verknüpfung:

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

und enthält alle möglichen ternären Rasteroperationen (SRCPAINT oder SRCAND sind wahrscheinlich das, was Sie suchen.).