Autor Beitrag
wdbee
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 628
Erhaltene Danke: 1



BeitragVerfasst: Do 11.10.07 13:03 
Hallo Leute,

in vielen Programmen muss ich Bilder von verschiedenen Kameras anzeigen. Das erledigt die Windows-API-Funktion StretchDIBits in der Regel ohne Probleme. Ohne Probleme? Nun, da gibt es ab und zu den Fall, dass die Funktion nichts ausgibt und 0 als Ergebnis liefert.

Im konkreten Fall werden die Bilder von 8 Kameras (640x480 und 1024x768, jeweils 256 Graustufen) in einem Canvas angezeigt. Zur Zeit werden von den 8 Kameras 6 korrekt angezeigt und 2 nicht! Der Code ist für alle gleich, nur der Index auf das Kameraarray bzw. deren Bildpuffer wird umgeschaltet. Es gibt auch Tage, da werden (ohne Änderungen am Programm/System) 9 Kameras korrekt angezeigt.

In anderen Anwendungen (viele verschiedene Grafikkarten/Rechner/Windows NT/XP usw.) hatte ich das Problem auch schon mal, konnte es aber immer dadurch umgehen, dass ich die Bildpuffer um ein Byte größer angelegt habe und das Bild dort ab dem zweiten Byte gespeichet habe.
Die Funktion StretchDIBits bekam dann einen Zeiger auf das zweite Byte und das Problem war weg.

Leider klappt das im aktuellen Fall nicht.

Irgendwelche Ideen?

Gruß

wdbee
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Do 11.10.07 13:17 
Welche Fehlermeldung spuckt GetLastError() aus, wenn StretchDIBits fehlschlägt ?

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
wdbee Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 628
Erhaltene Danke: 1



BeitragVerfasst: So 14.10.07 23:52 
Der Wert von GetLastError wird nicht verändert! Wenn vorher ein Fehler vorhanden war (z.B. "Keine weiteren Dateien vorhanden"), dann bleibt der Wert erhalten, war kein Fehler vorhanden, wird "Der Vorgang wurde erfolgreich beendet" geliefert.
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Mo 15.10.07 11:44 
Aus der Win32-SDK-Hilfe:

"If the function succeeds, the return value is the number of scan lines copied.
If the function fails, the return value is GDI_ERROR. To get extended error information, call GetLastError."

Wenn also GetLastError KEINEN Fehler zurückgibt, kann StretchDIBits nicht fehlgeschlagen sein. Ansonsten rufst du zum falschen Zeitpunkt GetLastError auf.

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
wdbee Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 628
Erhaltene Danke: 1



BeitragVerfasst: Mo 15.10.07 17:12 
Ich habe am Wochenende, als das Band stand, extra mal das Programm modifiziert und die beiden Aufrufe von GetLastError eingebaut. Den ersten Aufruf immer (direkt vor StretchDIBits), den zweiten dann, wenn StrechDIBits den Wert 0 zurückgibt (direkt nach StretchDIBits bzw. der if-Abfrage auf 0).

Der Test ergab die Aussage oben: GetLastError wird nicht verändert.
Damit hat StretchDIBits 0 Zeilen erfolgreich ausgegeben!
Leider hilft mir das nicht weiter.

In anderen Projekten hatte ich auch die einzelnen Parameter protokolliert, alles ohne Befund, die Werte waren immer gleich, egal ob das Bild angezeigt wurde oder nicht. Das einzige was anders war, war die Adresse des Bildpuffers. Das hatte mich damals auch auf die Idee gebracht, das Bild nicht ab dem ersten Byte des Puffers zu speichern, durch den Offset waren die Adressen immer ungerade und das Bild wurde immer dargestellt.

Leider ist das diesmal nicht so.
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Mi 17.10.07 11:55 
Ich habe mal gelesen, das manche Bitmaps "auf dem Kopf stehen" und somit einige Leute große Probleme bekamen. Vielleicht ist das in deinem Fall auch so ?

Wenn StretchDIBits eine 0 zurückgibt, einfach so tun, als sei Source auf dem Kopf und dann mit entsprechend geänderten Params nochmal StretchDIBitsen.

Nur ein Schuß ins Blaue, ich kann mir diese merwürdige Sache auch nicht so recht erklären.

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
wdbee Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 628
Erhaltene Danke: 1



BeitragVerfasst: Mi 17.10.07 14:12 
Die Kameras liefern in der Tat Bilder, die "Kopfstehen". Die Ausgabe wird dabei über das Vorzeichen der Bildhöhe gesteuert. Bei negativem Wert für die Bildhöhe, wird das Bild vertikal gespiegelt und damit "richtig" angezeigt.

Nun ist es halt so, dass das immer gleich gehandhabt wird und wunschgemäß funktioniert, wenn überhaupt ein Bild angezeigt wird. Das Programm zeichnet auf das "Hintergrundbild" (die Bitmap, die per StretchDIBits ausgegeben wird) noch diverse Linien zur Darstellung der erkannten Merkmale und das klappt immer, auch wenn die Bitmap fehlt!

Wenn das Programm das Bild einer Kamera einmal anzeigt, dann klappt es immer, wenn es nicht geht, dann von Anfang an und dauerhaft. Der einzige Parameter, der sich von Programmstart zu Programmstart ändert, ist die Lage des Bildpuffers im Speicher. Auch sind die anderen Parameter für alle Kameras (bzw. Kameragruppen 640x480 und 1024x768) immer gleich.

Deshalb der Versuch, die Lage des Bildes im Speicher zu beeinflussen.

Bei MS habe ich zwar einige Fehlerbeschreibungen gefunden, die z.B. sagen, dass die Funktion (in älteren Windowsversionen) Probleme hatte, wenn die Skalierung des Originals und der Darstellung sehr unterschiedlich sind. bei mir ist das aber nicht der Fall. Entweder wird 1:1 abgebildet oder 1:2.
wdbee Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 628
Erhaltene Danke: 1



BeitragVerfasst: Do 18.10.07 20:53 
Nachtrag:

Ich hatte heute Gelegenheit, das ganze noch etwas näher zu testen. Dabei zeigte sich, dass ich bisher von nicht ganz richtigen Voraussetzungen ausgegangen war. Der Kollege hatte den Versatz um ein Byte zwar eingebaut, aber nicht bei den einzelnen Bildpuffern, sondern nur beim Gesamtpuffer, in dem die Bildpuffer angelegt werden.

Wenn ich nun der Funktion StretchDIBits nicht den Zeiger auf das erste Byte des jeweiligen Bildpuffers übergebe sondern auf das zweite, wird das Bild wieder in allen Fällen angezeigt! Klar, dann ist die Anzeige um einen Pixel versetzt, aber es erfolgt eine Anzeige.

Der eigentliche Fehler bleibt unerklärlich, aber die Abhilfe lautet:

- Bildpuffer um ein Byte größer anlegen
- Zeiger auf den Bildpuffer um ein Byte inkrementieren und verwenden
- Vor dem Freigeben des Bildpuffers Zeiger wieder um ein Byte dekrementieren

Gruß

wdbee
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Fr 19.10.07 11:23 
Den Fehler und den "Hotfix" an MS melden - vielleicht finden die dann ja mal den Fehler in StretchDIBits... :D

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.