Probleme mit GDIplus und image.save
-
DrOetker schrieb:
Nun habe ich also eine Schleife, in der ich alle 0.002 Sekunden (änderbarer Time-Intervall) das Bild speichere. Merkwürdigerweise aber werden nur 69 Bilder gespeichert. Der Schleifeninhalt ist (vereinfacht):
record = true; for(int count = Anzahl;Anzahl!=0;Anzahl--){ if(record){ Screenshot* oScreenshot = new Screenshot(); oScreenshot->dump(targetFile.str().c_str()); delete oScreenshot; } }
Damit ich dich richtig verstehe: Wir in jedem Schleifendurchlauf ein Bild gespeichert? Oder wird diese for()-Schleife alle x Sekunden vom Timer neu gestartet?
(Zusatzfrage: Was steht überhaupt in 'Anzahl'?)
-
Ja, das hast Du richtig verstanden. Die Schleife ist ja wie gesagt vereinfacht - letztendlich wird aber bei jedem Durchlauf ein Bild gespeichert.
In Anzahl steht die Anzahl der Frames, die meine Anwendung durchläuft. Das berechne ich in einem anderen Teil, ist aber irrelevant, da Anzahl richtig ist (im konkreten Beispiel, das ich verwende, ist Anzahl immer 138...hola, genau die hälfte... aber das kann damit ja nichts zu tun haben...
-
Zwei Ideen:
a) Wird der Wert von 'record' irgendwo in der Schleife verändert?
b) Werden eigentlich immer die ersten 69 Bilder gespeichert? Oder jedes zweite Bild? (und wie sieht es aus, wenn du für Anzahl einen höheren Wert festlegst?)PS: und woher bekommst du den Dateinamen?
-
okay, also
zu a) nein, der wert wird nicht verändert. ich habe ja in meiner klasse in der funktion Screenshot::save die ausgabe
cout << error_name << strSave << endl;
diese wird auch korrekt ausgegeben.
zu b) ja, es werden die ersten 69 Bilder gespeichert. Das weiss ich, da die anwendung einen Roboter visuell bewegt, und dieser fährt einmal hin und einmal zurück. Daher kann ich das recht einfach kontrollieren.
Dateiname: der ergibt sich in der Schleife aus
std::ostringstream targetFile; targetFile << "C:/Temp/test" << pic_nr << ".png"; //(...) <- oben geposteter Code pic_nr++;
-
ich habe jetzt nochmal das ganze ausgelagert, und nicht mit der anwendung verbunden. ich habe also nur einen button, bei dem folgende schleife ausgeführt wird:
void CVidExpWin32Dlg::OnBnClickedButton2() { int pic_nr = 1000000, anzahl = 200; BOOL record = true; for(int i=0;i<anzahl;i++){ std::ostringstream targetFile; targetFile << "C:/Temp/test" << pic_nr << ".png"; if(record){ Screenshot* oScreenshot = new Screenshot(); oScreenshot->dump(targetFile.str().c_str()); delete oScreenshot; } pic_nr++; } }
es werden exakt nur 66 Bilder gespeichert!!
EDIT: ich habe jetzt mal nur jedes zehnte Bild abgespeichert. Auch dann tritt das Problem auf (Anzahl = 1000, nur jedes 10. Bild, ergibt 66 Bilder...).
Aber hier ist etwas im Debugger-Fenster, das wohl damit zu tun hat!
zuvor, wo speichern klappt, steht dort sehr viele Male:
The thread 'Win32 Thread' (0x7f8) has exited with code 1 (0x1).
und dann später:
The thread 'Win32 Thread' (0x1c0) has exited with code 0 (0x0).
Kann jemand damit was anfangen und hat einen Lösungsvorschlag? Da habe ich dann wohl doch irgendwie Ressourcenmäßig geschlampt bei meiner Klasse?
-
kann vielleicht noch irgend jemand schauen, wo ich Ressourcen nicht freigegeben / verschwendet habe? Vielleicht liegt da ja das Problem...
Ich bettel ja ungern, aber ich bin nicht faul - versuche und versuche, aber es haut nicht hin
-
Kannst du mal mit dem Debugger reingehen und nachschauen, was dort im Detail abläuft? Eventuell findest du dabei den Fehler.
-
Ja! Eben gerade habe ich herausgefunden, dass das Speichern nicht mehr funktioniert, da hBitmap in der Funktion Screenshot::Dump NULL ist! Das bringt mich dem Ganzen jetzt etwas näher - nur warum ist es NULL??
void Screenshot::dump(CString fileName) { HDC hdcSrc = GetWindowDC(GetDesktopWindow()), hdcDest = CreateCompatibleDC(hdcSrc); HBITMAP hBitmap = CreateCompatibleBitmap(hdcSrc, GetDeviceCaps(hdcSrc,8),GetDeviceCaps(hdcSrc,10)); SelectObject(hdcDest,hBitmap); BitBlt(hdcDest,0,0,GetDeviceCaps(hdcSrc,8), GetDeviceCaps(hdcSrc,10), hdcSrc,0,0,0x00CC0020); std::ostringstream oss; oss << "X: " << GetDeviceCaps(hdcSrc, HORZRES) << "Y: " << GetDeviceCaps(hdcSrc, VERTRES) << "\r\n"; writeDebug(oss.str().c_str()); if(hBitmap == NULL) writeDebug("hBitmap ist NULL!"); save(hBitmap,fileName); DeleteDC(hdcSrc); DeleteDC(hdcDest); DeleteDC((HDC)hBitmap); }
hdcSrc und hdcDest sind nicht NULL.
-
Siehe Antwort in
news:microsoft.public.de.vcDas wichtigest ist eigentlich nur, dass Du die Doku richtig liest...
Und da steht dass man bei einem "CreateCompatibleBitmap" ein "DeleteObject" aufrufen muss und bei einem "GetWindowDC" ein "ReleaseDC"...Also:
DeleteObject(hBitmap);
ReleaseDC(hDesktop, hdcSrc);
-
Ach, dass Du hier auch unterwegs bist
Hier stand es zuerst, aber ich bekam keine Hilfe. Werde ich morgen gleich testen, danke soweit.
Ich habe auch in die Hilfe geschaut, leider ist das Problem nur dass die nur Links für die MFC Komponenten bereithält, aber wie ich nun bemerkt habe die Funktionen von GDIPlus bei mir irgendwie nicht aufgelistet werden. Nunja, morgen bin ich schlauer! Danke soweit.