Hallo,
ich habe ein paar Programme die Pixeldaten des Bildschirms per BitBlt() der GDI32 auslesen um z.B. eine Lupe zu realisieren.
Bis Windows 7 konnte man Aero (WDM) deaktivieren. Ist Aero aktiv dauert das auslesen per BitBlt unverhältnismäßig lange und ist für mich so einfach zu langsam. Ich bin jetzt auf Windows 8 umgestiegen, kann Aero dort allerdings nicht deaktivieren...
Weiß jemand wie man BitBlt auch mit aktiviertem Aero performant hinbekommt? Ich möchte auch nicht meine Programme alle komplett umschreiben also wäre eine ANpassung der vorhandenen Methoden wünschenswert.
Gruß
-Hades-
Unter Windows 8 ist Aero deaktiviert. Zum Glück.
Es gibt aber einige Tricks wie man Aero unter Windows 8 aktivieren kann.
Grüße Bernd
Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3
Hallo BernFfm,
also wenn Aero in Windows 8 deaktiviert ist dann ist das anscheinend nicht mein Problem. Es ist nur so, dass das Problem des langsamen Pixelauslesens immer dann auftritt wenn (unter Windows 7/ XP) Aero aktiv ist. Der Windows Desktop Manager ist wohl irgendwie dran Schuld weil die Fenster der einzelnen Prozesse separat behandelt werden.
Wie dem auch sei, kennt jemand das Problem und weiß eine Lösung dafür?
Hallo -Hades-,
hast du es schon mit Graphics.CopyFromScreen probiert?
herbivore
Hallo Herbivore,
CopyFromScreen habe ich seinerzeit als erstes getestet, da es der einfachste Weg war, allerdings war das extrem langsam verglichen zu BitBlt. Hat sich das mittlerweile geändert?
Ich hab in den Source geschaut, CopyFromScreen ruft im Endeffekt auch nur BitBlt auf, wesentlich langsamer kanns also nicht sein. Das einzige, was es zusätzlich macht ist sich eine UiPermission zu holen, das wird wohl nicht lang dauern.
Ah ok,
dann weiß ich auch nicht genau warum das bei mir damals langsamer war. Allerdings besteht ja noch immer das Ausgangsproblem mit Aero beziehungsweise dem WDM...
Hallo Herbivore,
ich habe jetzt endlich Zeit gefunden mir die Magnification API anzusehen. Diese funktioniert sehr gut und ist selbst bei einer Auflösung von 1920x1200 sehr flott, also wenn man den kompletten Screen vergrößern lässt.
Allerdings gibt es 2 "Probleme" damit. Erstens ist es zur Zeit eine reine C++ Bibliothek, zweitens bin ich dadurch auf die Funktionalität der API beschränkt. Ich brauche etwas mehr als nur die Vergrößerung. So würde ich gerne erst ein wenig Computer Vision betreiben bevor ich etwas vergrößere. Also z.B. wenn ich über ein Bild gehe möchte ich gerne im Vorfeld erkennen das es sich um ein Gesicht oder einfach nur Hautpartien handelt.
Dazu brauche ich allerdings die Pixelinformationen. Also schlussendlich würde ich gerne eine Bitmap erhalten, auf der ich arbeiten kann.
Ich habe in der Magnification API die MagSetImageScalingCallback Methode gefunden, welche das handle des MagnificationWindow annimmt und eine Callback Methode. Darüber ist es anscheinend möglich an die Pixelinformationen zu gelangen, da diese meines erachtens als void* an die Callback-Methode übergeben werden.
Ich habe eine Callback-Methode implementiert:
BOOL CALLBACK myCallBackMethod(HWND hwnd, void* srcdata, MAGIMAGEHEADER srcheader, void* destdata, MAGIMAGEHEADER destheader, RECT unclipped, RECT clipped, HRGN dirty) {
return true;
}
Beim Return habe ich einen Breakpoint gesetzt, und in den Parametern steht auch verwertbares drin (hoffe ich), allerdings kenne ich mich nicht so gut mit C++ aus.
Meine Frage ist jetzt, wie ich die zurückgegebenen Daten in ein Bitmap und am besten noch gescheit ins C# bekomme. Also ein C# delegat als Callback wäre wahrscheinlich am sinnvollsten für mich aber ich bin froh über alles was funktioniert.
Achso, als ich nach dem Breakpoint weitergelaufen lassen habe, hat mein Desktop nicht mehr reagiert, kein Fenster wurde mehr angezeigt, so dass ich rebooten musste, vielleicht weiß ja jemand was da passiert ist.
Gruß -Hades-
Hallo -Hades-,
die man aus einer C-(Callback)-Methode eine C#-Methode aufrufen kann, sollte sich im Netz leicht finden lassen.
herbivore
Hmm ok, das werde ich dann mal suchen, also du meinst am besten eine C# Methode innerhalb der C-Callback-Methode aufrufen?
Könntest du mir denn vielleicht erklären wie ich die Daten (void*) in eine Bitmap bekomme?
Vielleicht hilft das: Convert Raw memory pointer to Bitmap/Graphics object ( unsafe code )
cSharp Projekte : https://github.com/jogibear9988
Hey danke yogibear,
mit dem Bitmapkonstruktor wäre das ja übertrieben einfach und ich dachte ich muss die Bytes Zeile für Zeile durchgehen... Hoffe das funktioniert auch, werde es ausprobieren.