Entwickler-Ecke
Windows API - Screenshot mit BitBlt, Unterschiede zwischen WinXP und Vista
Schlitzesofa - Do 08.01.09 19:21
Titel: Screenshot mit BitBlt, Unterschiede zwischen WinXP und Vista
Hallo,
ich habe ein Programm geschrieben, welches mit BitBlt Screenshots anfertigt und in diesen Screenshots nach Symbolen sucht.
Die Sysmbole werden dabei mit abgespeicherten Referenz-Bitmaps auf Indentität verglichen. (z.B. Buchstaben für die Schrifterkenung)
Das funktioniert unter Windows XP auch einwandfei.
Nun habe ich letztens das Programm unter Vista laufen lassen und muste feststellen, daß er zwar den Screenshot macht, aber die Symbole nicht mehr erkennt. Meine Vermutung ist, daß es was mit der Farbtiefe zu tun hat. Denn wenn ich ein Screenshot in Windows XP mache und ihn dann in Vista als Bild öfnne, dann erkennt mein Programm innerhalb dieses Bildes wieder alle Symbole.
In beiden Betriebssystemen habe ich die Anzeige auf 32 Bit gestellt.
Gibt es evt. irgendwelche Unterschiede im Befehl BitBlt zwischen WinXP und Vista? Oder werden in Vista die Farben evt. durch irgendelche DirectX-Routinen "verschmiert"?
hier mein Quelltext:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| procedure ScreenCapture(Bmp: TBitmap); var DeskWnd: HWnd; DeskDC: HDC; DeskCv: TCanvas; R: TRect; W, H: Integer; begin if Bmp = nil then Exit; DeskWnd := GetDesktopWindow; DeskDC := GetWindowDC(DeskWnd); DeskCv := TCanvas.Create; DeskCv.Handle := DeskDC; W := Screen.Width; H := Screen.Height; R := Bounds(0, 0, W, H); try Bmp.HandleType := bmDIB; Bmp.PixelFormat := pf24Bit; Bmp.Width := W; Bmp.Height := H; Bmp.Canvas.CopyMode := cmSrcCopy; Bmp.Canvas.CopyRect(R, DeskCv, R); finally DeskCv.Free; ReleaseDC(DeskWnd, DeskDC); end; end; |
P.S.:
Ich weiß, daß ich die Farbtiefe im Quelltext auf 24 Bit gestellt habe (die Anzeige ist auf 32 Bit eingestellt), aber das Proramm funktioniert ja trotzdem in XP. Ich habe sie auch schon auf 32 Bit umgestellt, was aber auch nicht funktioniert (kein Wunder, denn die Refrenz-Bilder sind vermutlich 24 Bit Farbtiefe).
Vielen Dank
Moderiert von
Narses: Delphi-Tag repariert
elundril - Do 08.01.09 19:25
hallo und :welcome: im DF,
bitte umrahme deinen quelltext zur besseren lesbarkeit mit den delphi-tags: [delphi][/delphi]
lg elundril
Hidden - Do 08.01.09 20:30
Hi :)
Ich befürchte du hast unter deinem post das Häkchen "BBCode in dieser Nachricht deaktivieren" gesetzt. Mach das mal weg, dann kann man deinen Quelltext auch lesen ;)
mfG,
JayEff - Do 08.01.09 21:14
Hidden hat folgendes geschrieben : |
Hi :)
Ich befürchte du hast unter deinem post das Häkchen "BBCode in dieser Nachricht deaktivieren" gesetzt. Mach das mal weg, dann kann man deinen Quelltext auch lesen ;)
mfG, |
Nein, es ist der zweite öffnende Delphi-tag der mitten im Code steht:
Bmp.Han[delphi]dleType := bmDIB; ;) den sollte man entfernen.
jaenicke - Do 08.01.09 21:24
Titel: Re: Screenshot mit BitBlt, Unterschiede zwischen WinXP und V
Schlitzesofa hat folgendes geschrieben : |
Die Sysmbole werden dabei mit abgespeicherten Referenz-Bitmaps auf Indentität verglichen. (z.B. Buchstaben für die Schrifterkenung) |
Woher stammen denn diese Referenz-Bitmaps?
Schlitzesofa - Fr 09.01.09 16:16
Titel: Re: Screenshot mit BitBlt, Unterschiede zwischen WinXP und V
jaenicke hat folgendes geschrieben : |
Schlitzesofa hat folgendes geschrieben : | Die Sysmbole werden dabei mit abgespeicherten Referenz-Bitmaps auf Indentität verglichen. (z.B. Buchstaben für die Schrifterkenung) | Woher stammen denn diese Referenz-Bitmaps? |
Zunächst erstmal danke für die korrekte Darstellung meines Quelltextes. Es war mein erstes mal, da habe ich wohl mal aus Versehen den falschen Knopf gedrückt.
Also die Referenzbilder sind selbst auch aus Screenshots extrahiert (in WinXP angefertigt).
Also Screenshot --> in Paint ausschneiden und als Bitmap abspeichern.
Wahrscheinlich würde es funktionieren, wenn ich die Referenzbilder für Vista aktualisieren würde, doch das ist mir zu viel Arbeit.
jaenicke - Fr 09.01.09 16:26
Das Problem ist doch, dass unter Vista die Icons ohnehin andere sind, sei es für Textdateien oder andere. Zudem macht es bei der Beschriftung einen Unterschied, ob ClearType aktiviert ist oder nicht. Zudem kann ich die Icongröße auf dem Desktop ja jederzeit ändern. Genauso wie die Farbtiefe. Oder den Abstand der Icons untereinander.
Worum es dir genau geht bei der Erkennung weiß ich ja nicht, aber bei allgemeinen Fällen wird das so nichts.
Wenn du also nicht von deinem Programm auf dem Zielsystem die Referenzbilder im Rahmen einer Einrichtung anfertigen lässt, dann wirst du da nicht viel Erfolg haben fürchte ich. :nixweiss:
Eine sinnvollere Alternative wäre vielleicht der Weg, den Programme gehen, die sich die Positionen der Symbole auf dem Desktop merken und wiederherstellen. Die greifen auf die Symbole ja direkt zu, und dann kann man von dort aus auch das aktuelle Symbol direkt auslesen, also dessen Pfad.
Schlitzesofa - Sa 10.01.09 03:48
jaenicke hat folgendes geschrieben : |
Das Problem ist doch, dass unter Vista die Icons ohnehin andere sind, sei es für Textdateien oder andere. Zudem macht es bei der Beschriftung einen Unterschied, ob ClearType aktiviert ist oder nicht. Zudem kann ich die Icongröße auf dem Desktop ja jederzeit ändern. Genauso wie die Farbtiefe. Oder den Abstand der Icons untereinander.
Worum es dir genau geht bei der Erkennung weiß ich ja nicht, aber bei allgemeinen Fällen wird das so nichts.
Wenn du also nicht von deinem Programm auf dem Zielsystem die Referenzbilder im Rahmen einer Einrichtung anfertigen lässt, dann wirst du da nicht viel Erfolg haben fürchte ich. :nixweiss:
Eine sinnvollere Alternative wäre vielleicht der Weg, den Programme gehen, die sich die Positionen der Symbole auf dem Desktop merken und wiederherstellen. Die greifen auf die Symbole ja direkt zu, und dann kann man von dort aus auch das aktuelle Symbol direkt auslesen, also dessen Pfad. |
Es geht mir nicht um Icons oder Desktop-Verknüpfungen,
sondern mir geht es darum, daß die Software aus einem Programmfenster Zahlen und zum Teil auch Buchstaben ausliest.
Dazu habe ich die Zahlen 0 bis 9 und auch einige betroffene Buchstaben bzw. Wörter vorher mittels Screenshots abgespeichert und als Referenz-Bitmaps hinterlegt.
Das ganze ist notwendig, wenn man Programme überwachen will, die über keine vorgesehene Programmier-Schnittstelle verfügen.
Es ist also auch davon auszugehen, daß die Darstellung innerhalb des Programmfensters unabhängig vom verwendeten Betriebssystem ist (es sei denn Vista legt irgendwelche Effekte drüber, was ich eben nicht genau weiss).
JayEff - Sa 10.01.09 05:24
Kann man nicht die fensterhandles der ausgabeelemente suchen und ihre eigenschaften auslesen? Ich weiß nicht genau wie das geht, aber ich glaube doch, es müsste gehen...?
jaenicke - Sa 10.01.09 11:20
Schlitzesofa hat folgendes geschrieben : |
Es ist also auch davon auszugehen, daß die Darstellung innerhalb des Programmfensters unabhängig vom verwendeten Betriebssystem ist (es sei denn Vista legt irgendwelche Effekte drüber, was ich eben nicht genau weiss). |
Ja, tut es und XP ggf. auch, ClearType z.B. nämlich. Hast du die gemachten Screenshots von XP und Vista mal auf solche Unterschiede hin verglichen?
ListViews, TreeViews, etc. kann man übrigens auch direkt auslesen, wie
JayEff auch sagte:
http://www.delphipraxis.net/topic52045_fremde+treeview+auslesen.html
Schlitzesofa - Sa 10.01.09 16:49
jaenicke hat folgendes geschrieben : |
Schlitzesofa hat folgendes geschrieben : | Es ist also auch davon auszugehen, daß die Darstellung innerhalb des Programmfensters unabhängig vom verwendeten Betriebssystem ist (es sei denn Vista legt irgendwelche Effekte drüber, was ich eben nicht genau weiss). | Ja, tut es und XP ggf. auch, ClearType z.B. nämlich. Hast du die gemachten Screenshots von XP und Vista mal auf solche Unterschiede hin verglichen?
ListViews, TreeViews, etc. kann man übrigens auch direkt auslesen, wie JayEff auch sagte:
http://www.delphipraxis.net/topic52045_fremde+treeview+auslesen.html |
Vielen Dank,
ClearType war des Rätsels Lösung!
Ich habe es abgeschalten und jetzt funktioniert die Zahlenerkennung wieder.
HPW - Do 29.01.09 09:29
Hallo,
Zitat: |
Die Sysmbole werden dabei mit abgespeicherten Referenz-Bitmaps auf Indentität verglichen. |
Mit welchem Algorithmus wird das denn gemacht?
Wenn man bei jedem Pixel (Scanline) anfängt den Bereich der linken oberen Ecke jeder Referenz-Bitmap zu vergleichen, wird das doch sehr aufwendig und un-performant oder?
Hans-Peter
jaenicke - Do 29.01.09 14:22
Hallo und :welcome:!
HPW hat folgendes geschrieben : |
Mit welchem Algorithmus wird das denn gemacht?
Wenn man bei jedem Pixel (Scanline) anfängt den Bereich der linken oberen Ecke jeder Referenz-Bitmap zu vergleichen, wird das doch sehr aufwendig und un-performant oder? |
Eine große Wahl hast du dabei ja nicht. Irgendwie musst du die Pixel ja vergleichen. Wobei du bei exakter Identität auch sehr schnell mit CompareMem arbeiten kannst.
Ansonsten gibt es hier auch etwas zu dem Thema:
http://www.delphi-forum.de/viewtopic.php?p=529340#529340
(diese Ergänzung bezog sich auf den Quelltext weiter oben.)
Aber wenn du dazu eine Frage hast, dann erstelle bitte auch ein entsprechendes Thema.
HPW - Do 29.01.09 16:14
Danke für die Info und den Link.
Ich dachte es gäbe hier vielleicht einen besseren Ansatz/Algorithmus.
Zitat: |
Aber wenn du dazu eine Frage hast, dann erstelle bitte auch ein entsprechendes Thema. |
Werde ich tun wenn dazu noch weitere Fragen aufkommen.
Danke
Hans-Peter
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!