In Bitmap speichern...
-
Also du verwendest bis jetzt folgenden Code:
CBitmap bitmap; bitmap.CreateBitmap( 1000, 900, 1,24, NULL ); CDC MemDC; CDC* pDC = GetDC(); MemDC.CreateCompatibleDC( pDC ); MemDC.SelectObject(bitmap); HBITMAP hBitmap=bitmap; ZeichneEtwas(&MemDC); WriteBitmap("c:\test", hBitmap, MemDC);Da fehlt nur noch ein wenig.
CBitmap bitmap; bitmap.CreateBitmap( 1000, 900, 1,24, NULL ); CDC MemDC; CDC* pDC = GetDC(); MemDC.CreateCompatibleDC( pDC ); MemDC.SelectObject(bitmap); ZeichneEtwas(&MemDC); pDC->SelectObject(bitmap); pDC->BitBlt(0,0,1000,900, &MemDC, 0,0, SRCCOPY); //Inhalt des MemDC in Bitmap blitten WriteBitmap("c:\\test.bmp", Bitmap.operator HBITMAP(), pDC->m_hDC);Sollte das nicht gehen wäre es gut mal ins Projekt zu sehen, kannst Du eventl.
das Projekt zipped irgendwohin stellen? (ohne Debug Verzeichnis!)Gruss
-
Leider funktoniert es immer noch nicht. Es passiert einfach gar nichts, keine Datei wird erstellt
Das Projekt kann ich leider nicht zeigen, ist für eine Firma. Ich habe mal eine komplett neue Klasse erstellt, mit einem "Save" Button und will nur eine Linie in das Bitmap zeichnen:void CZeichnen::OnSave() { CBitmap bitmap; bitmap.CreateBitmap( 1000, 900, 1,24, NULL ); CDC MemDC; CDC* pDC = GetDC(); MemDC.CreateCompatibleDC( pDC ); MemDC.SelectObject(bitmap); MemDC.MoveTo(10,10); MemDC.LineTo(100,100); pDC->SelectObject(bitmap); pDC->BitBlt(0,0,1000,900, &MemDC, 0,0, SRCCOPY); WriteBitmap("c:\\test.bmp", bitmap.operator HBITMAP(), pDC->m_hDC); }Das müßte doch auf jeden Fall funktionieren, unabhängig vom rest des Codes, oder???
-
Ich kann jetzt erstmal nur noch empfehlen durch die WriteBitmap mit dem Debugger zu gehen und mit die Stelle wo er mit welchem Ergebnis aussteigt...
Wenn man nicht reinsehen kann ist es schwer ;), aber OK - muss man halt durch
Also poste mir mal das Zeug, dann sehen wir weiter.
-
Hab es debugt, er führt diese Anweisung nicht aus:
if(GetDIBits(memdc, hbitmap, 0, BmpInfoHdr.biHeight, bmp.bmBits, (BITMAPINFO*)&BmpInfoHdr, DIB_RGB_COLORS) == BmpInfoHdr.biHeight)Hier die Ergebnisse:
- BmpFileHdr {...}
bfType 19778
bfSize 2700054
bfReserved1 0
bfReserved2 0
bfOffBits 54
- BmpInfoHdr {...}
biSize 40
biWidth 1000
biHeight 900
biPlanes 1
biBitCount 24
biCompression 0
biSizeImage 2700000
biXPelsPerMeter -858993460
biYPelsPerMeter -858993460
biClrUsed 3435973836
biClrImportant 3435973836
+ this 0x00120648 {CZeichnen hWnd=0x0b8c0720}
- szFile 0x00602268 "d:\test.bmp"
100 'd'
- hbitmap 0x4b050683
unused CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden
- memdc 0xa6010215
unused CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden
- bmp {...}
bmType 0
bmWidth 1000
bmHeight 900
bmWidthBytes 3000
bmPlanes 1
bmBitsPixel 24
bmBits 0x01610020Hoffe du kannst damit etwas anfangen...
Nochmal vielen Dank für deine Hilfe!
-
Jetzt hab ich mal die if-Schleife auskommentiert (also NUR das if und == BmpInfoHdr.biHeight), dann erhalte ich eine Datei, allerdings ist sie komplett schwarz!
-
Ich mach nacher (wird leider erst so in 20 Minuten werden) mal ein MFC-Projekt
wo eine Bitmap erzeugt (male irgendwas rein) und dann gespeichert wird. Das Projekt stell ich dann auf ne HP wo Du es ziehen kannst - also nur die Sourcen (keine EXE). Nimm das als Referenzprojekt und wenn dann noch Fragen sind meld dich halt wieder...
-
Das wär echt Klasse, vielen Dank schon mal im vorraus!!! Macht nix wenn es etwas länger geht, arbeite eh erst morgen dran weiter!
Viele Grüße
Christian
-
So nun ist das Projekt fertig, aber dummerweise hab ich meine URL-PWD nicht mit in der Stadt wo ich gerade arbeite. Ich hab ein MFC-SDI Projekt erzeugt und nur die OnPaint gefüllt, bei mir wird sauber eine Bitmap erzeugt. Den Quellcode der WriteBitmap habe ich nicht verändert.
Also vielleicht hilft die auch der Code der OnPaint:
void CChildView::OnPaint() { CPaintDC dc(this); // Gerätekontext zum Zeichnen //na dann, malen wir mal irgendwas was ins HDC dc.Rectangle(rand()%50,rand()%50,600, 600); RECT r; CBrush brush; r.left=rand()%50; r.top=rand()%50; r.bottom=rand()%800; r.right=rand()%800; brush.CreateSolidBrush(RGB(255,255,0)); //ein gelbes Rechteck dc.FillRect(&r, &brush); //auch noch einen Text dc.TextOut(100,100,"Das ist ein Text in einer Bitmap!"); //jetzt das ganze als Bitmap abspeichern CBitmap bmp; //Bitmap-Objekt CDC memdc; //Speicherkontext RECT cr; //für die Grösse des Clients memdc.CreateCompatibleDC((CDC*)&dc); GetClientRect(&cr); //Ausdehnung des Clientsbereichs ermitteln //passende Bitmap in der Grösse des Clients anlegen bmp.CreateCompatibleBitmap((CDC*)&dc, cr.right,cr.bottom); //Speicherkontext mit der Bitmap verbinden memdc.SelectObject(bmp); //In den Speicherkontext (eigentlich in die Bitmap!) den Inhalt des dc kopieren memdc.BitBlt(0,0,cr.right,cr.bottom,(CDC*)&dc,0,0,SRCCOPY); //Jetzt die Bitmap speichern WriteBitmap("c:\\testbitmap.bmp",bmp.operator HBITMAP(), memdc.m_hDC); // Rufen Sie nicht CWnd::OnPaint() für Nachrichten zum Zeichnen auf }Bei mir funktioniert das wie es soll. Wenn man das Fenster scaliert, wird immer
eine neue Zeichnung erstellt und in die Bitmap-Datei geschrieben.
Sollte für ne Demo auch reichen...Schreib wieder bei Fragen.
Gruss René
-
Vielen Dank, werd es gleich morgen ausprobieren, sobald ich auf arbeit bin!
Werd dann das Ergebnis hier posten!Schönen Abend noch und viele Grüße
Christian
-
Jetzt habe ich mal kurz eine dialogf. Anwendung erstellt mit einem Button "Speichern" in OnClicked() habe ich den Code kopiert. Jetzt wird zwar ein Bitmap erstellt aber in diesem ist ein Screenshot von meinem Dialog!! Liegt das daran dass ich es nicht in OnPaint() oder wie kann denn das kommen??
-
Also gut, dann bis morgen und auch schönen Feierabend!
Gruss René
-
Guten morgen

Das funktioniert jetzt alles echt wunderbar, nur ein Problem besteht noch: Er zeichnte mir das was er in die Datei zeichnet auch auf den Bildschirm!! Dadurch überschreibt er mir meine Grafik! Erst wenn ich das Fenster minimiere und wieder maximiere ist wieder alles beim alten! Hast du dafür eine Lösungsidee??
-
Das Problem stellt sich doch noch etwas anderst dar, er macht folgendes: Er zeichnet erst auf den Bildschirm, macht dann vom ganzen Bildschirm einen Screenshot und speichert das in der Datei. Wenn ich nämlich den Bereich größer mache sehe ich sogar die Taskleiste im Bitmap!

Ich verzweifle

-
Du musst halt meine Zeichenfunktionen rausnehmen und Du solltest auch GetCLientRect aufrufen um die Grösse deines Zeichenfensters zu ermitteln.
Ich hab in dem Beispiel die Bitmap genau in dessen Grösse erstellt. Machst
Du die Bitmap grösser bekommst du auch Pixel ausserhalb Deines Fensters in die Bitmap gelegt
gruss
-
Ja, das hab ich schon gemacht, aber das Problem ist halt dass in die Bitmap etwas anderes soll als das was auf dem Bildschirm ist, deshalb muß sie ja auch größer sein! Das in der bitmap soll total unabhängig von dem aufm Bildschirm sein!
-
Also ich konnte Dir nur soweit helfen das Du eine Bitmap erzeugen kannst.
Um jetzt nun genau zu wissen WAS in die Bitmap rein soll, muss ich halt auch mal
in den Code sehen können. Da das nicht geht, brauche ich dann eben ganz detailierte Informationen
darüber. Sonst wird das ganz schwer und ist nur ein rumgerate und probieren...
gruss
-
Okay, also ich versuch das mal zu erklären:
Ich habe neben vielen, vielen anderen Funktionen, die alle etwas auf den Bildschirm zeichnen diese Funktion://Zeichnet das Koordinatensystem CZeichnen::ZeichneKoordinatensys(CDC *pDC) { double druckenVerschieb=0; if(m_druckenFaktor.x!=1) druckenVerschieb=m_druckenMitte.x; //Y-Achse mit Pfeil pDC->MoveTo(80*m_druckenFaktor.x,605*m_druckenFaktor.y+druckenVerschieb); pDC->LineTo(80*m_druckenFaktor.x,100*m_druckenFaktor.y+druckenVerschieb); pDC->MoveTo(80*m_druckenFaktor.x,100*m_druckenFaktor.y+druckenVerschieb); pDC->LineTo(75*m_druckenFaktor.x,107*m_druckenFaktor.y+druckenVerschieb); pDC->MoveTo(80*m_druckenFaktor.x,100*m_druckenFaktor.y+druckenVerschieb); pDC->LineTo(85*m_druckenFaktor.x,107*m_druckenFaktor.y+druckenVerschieb); //X-Achse mit Pfeil pDC->MoveTo(75*m_druckenFaktor.x,600*m_druckenFaktor.y+druckenVerschieb); pDC->LineTo(700*m_druckenFaktor.x,600*m_druckenFaktor.y+druckenVerschieb); pDC->LineTo(693*m_druckenFaktor.x,595*m_druckenFaktor.y+druckenVerschieb); pDC->MoveTo(700*m_druckenFaktor.x,600*m_druckenFaktor.y+druckenVerschieb); pDC->LineTo(693*m_druckenFaktor.x,605*m_druckenFaktor.y+druckenVerschieb);So, wenn der Anwender jetzt auf den "Speichern" Button klickt, dann soll diese, und NUR diese Funktion in ein Bitmap mit weißem Hintergrund gezeichnet und gepseichert werden.
Ich habe jetzt folgendes probiert:void CZeichnen::OnSave() { static char BASED_CODE szFilter[]="Bitmap-Dateien (*.bmp)|*.bmp||"; CString filename; CFileDialog saveFile(FALSE, ".bmp", filename, OFN_HIDEREADONLY,szFilter); if(saveFile.DoModal()==IDOK) { CDC *cdc; cdc=GetDC(); cdc->Rectangle(0,0,900, 1000); ZeichneKoordinatensys(cdc); //jetzt das ganze als Bitmap abspeichern CBitmap bmp; //Bitmap-Objekt CDC memdc; //Speicherkontext RECT cr; //für die Grösse des Clients cr.right=900; cr.bottom=1000; //memdc.CreateCompatibleDC((CDC*)&cdc); memdc.CreateCompatibleDC(NULL); //GetClientRect(&cr); //Ausdehnung des Clientsbereichs ermitteln //passende Bitmap in der Grösse des Clients anlegen bmp.CreateCompatibleBitmap((CDC*)cdc, cr.right,cr.bottom); //Speicherkontext mit der Bitmap verbinden memdc.SelectObject(bmp); memdc.BitBlt(0,0,cr.right,cr.bottom,(CDC*)cdc,0,0,SRCCOPY); //Jetzt die Bitmap speichern filename=saveFile.GetPathName(); WriteBitmap(filename,bmp.operator HBITMAP(), memdc.m_hDC); } }Das funktioniert jetzt ja auch alles soweit, nur das Problem ist jetzt eben, dass unter das Koordinatensystem auch noch Text soll, aber da ist die Taskleiste in meinem Bitmap zu sehen und darunter nur noch schwarz! Dort soll aber einfach nur ein weißer Bereich sein, in den ich noch mehr zeichnen bzw. schreiben kann.
Ich hoff die ganze Erklärung ist einigermaßen verständlich geschrieben.

-
sag mal darf ich deinen Namen als Destruktoraufruf ansehen
-
Ne, nur Christian war einfach schon belegt, und in nem anderen C++ Forum werden bei unregistrierten immer das ~ vorangestellt, also hab ich das hier auch gemacht...
Gruß Christian
-
Nur mal ne schnelle Lösung, für genaueres muss ich nacher nochmal den Code durchgehen.
Das Problem ist derzeit, das die Bitmap zwar gross genug ist, aber nur der der
Teil des DC reinkopiert wird, wie eben das Fenster gross ist. Die Lösung sollte
sein die Bitmap VOR deinen eigentlichen Zeichenfunktionen erstmal komplett Weiss zu füllen
(damit ist dann auch die Taskleiste ect. weg) und dann die Zeichenoperationen auf die Bitmap
auszuführen. Dazu solltest Du in der CZeichnen::ZeichneKoordinatensys(CDC *pDC);
zuerst ein pDC->FillRect()
aufrufen und dabei die Koordinaten left=0,top=0,right=900,bottom=1000 im zu übergebenen LPRECT eintragen.Mal sehen ob das schon reicht, sonst später was anderes.
gruss RenéPS: Leider muss ich nebenbei ein wenig arbeiten, kann also ein wenig dauern
