Laden...

BitBlt dauert unter bestimmten Umständen (Aero?, Windows 8?) zu langsam

Erstellt von -Hades- vor 10 Jahren Letzter Beitrag vor 10 Jahren 3.645 Views
-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 10 Jahren
BitBlt dauert unter bestimmten Umständen (Aero?, Windows 8?) zu langsam

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-

3.825 Beiträge seit 2006
vor 10 Jahren

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

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 10 Jahren

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?

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo -Hades-,

hast du es schon mit Graphics.CopyFromScreen probiert?

herbivore

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 10 Jahren

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?

C
1.214 Beiträge seit 2006
vor 10 Jahren

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.

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 10 Jahren

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...

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 10 Jahren

Weiß da niemand einen Rat?

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo -Hades-,

hast du es schon mit dem Magnification API probiert?

herbivore

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 10 Jahren

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-

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo -Hades-,

die man aus einer C-(Callback)-Methode eine C#-Methode aufrufen kann, sollte sich im Netz leicht finden lassen.

herbivore

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 10 Jahren

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?

J
641 Beiträge seit 2007
vor 10 Jahren

cSharp Projekte : https://github.com/jogibear9988

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 10 Jahren

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.

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 10 Jahren

Ok funktioniert jetzt alles, danke für die Tipps.