CDC Objekt mit CImage als bmp speichern
-
Ich denke zwar nicht das dein Problem die größe deiner Bitmap is, aber wenn du das Bitmap beschneiden willst, geht das doch ganz einfach. Erstelle ein neues Bitap in der gewünschten Zielgröße und blitte den gewünschten ausschnitt aus der Quelle in das Ziel. Zum Schluß Ziel Speichern und fertig.
Gruß Matthias
-
so... hab das nun ein bissel anders gemacht...
und zwar hab ich mir gedacht ich zeichne das gleich in ne bitmap...
so bin ich auch gleich das Attach-Problem los... es kommt kein fehler mehr.
doch leider ist meine bitmap vollkommen schwarz... weiß jemand, wo das problem liegen könnte...
wird da nichts reingezeichnet, oder speichert er den falschen bereich...hier die draw-funktion mit eingebauter bitmap speicherung:
void CPOCView::OnDraw(CDC* pDC) { GetClientRect(&crect); CPOCDoc* pDoc=(CPOCDoc*)GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; int w=(int)((double)pDoc->PLAYGROUND_WIDTH*pDoc->zoomfac); int h=(int)((double)pDoc->PLAYGROUND_HEIGHT*pDoc->zoomfac); pDC->SetWindowOrg(0,h); pDC->SetWindowExt(w,-h); int i; if (!(pDoc->clickmode==CLICK_COMP_ACTIVE || pDoc->clickmode==CLICK_NODE_ACTIVE) && pDoc->SHOWLEGEND) { DrawLegend(pDC,pDoc); } for (i=0;i<pDoc->numcomponents;i++) { DrawComponent(pDC,pDoc,i); } if (!(pDoc->clickmode==CLICK_COMP_ACTIVE && pDoc->toolmode==TOOL_MOVE)) { for (i=0;i<pDoc->N;i++) { for (int j=0;j<i;j++) { DrawLink(pDC,pDoc,i,j); } } for (i=0;i<pDoc->N;i++) { DrawNode(pDC,pDoc,i); } } pDC->MoveTo(0,0); pDC->LineTo(0,h); pDC->LineTo(w,h); pDC->LineTo(w,0); if(pDoc->getCreateBMP() == true) { //to enter the if-area just one time fpr each file pDoc->setCreateBMP(false); //create a DC for drawing directly in a bitmap CDC pDC2; pDC2.CreateCompatibleDC(pDC); pDC2.SetMapMode(MM_TEXT); pDC2.SetWindowOrg(0,h); pDC2.SetWindowExt(w,-h); CRect rcClip, rcClient; pDC->GetClipBox( &rcClip ); GetClientRect(&rcClient); //Select a compatible bitmap into the bitmap DC CBitmap bitmap; bitmap.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height()); pDC2.SelectObject( &bitmap ); //Set clip region to be same as that in draw DC CRgn rgn; rgn.CreateRectRgnIndirect( &rcClip ); pDC2.SelectClipRgn(&rgn); rgn.DeleteObject(); //now drawing into the bitmap CPOCView::OnDraw(&pDC2); //CImage erstellen CImage image; //Bitmap zuweisen image.Attach(bitmap); //Bitmap speichern image.Save(L"C:\\test.bmp"); /*TODO: ersetzen durch pDoc->OnBMPCreation()*/ } }
ab zeile 46 geht der abschnitt für die bitmap erstellung los
doch wie gesagt, speichert er nur eine schwarze bitmap-datei ab
-
Also nur mal schnell drüber geschaut is mir aufgefallen:
1. was brauchst du SetMapMode,SetWindowOrg,SetWindowExt in deinem memdc
2. was soll die clipbox bewirken wenn du die
3. zum erstellen einer Rectrgn die du dann
4. nachdem du die in deinem memdc selectiert hast gleich wieder löschst
5. übergibst du ondraw deine memdc, weiss net ob das geht weil ich hab immer aus dem screendc und den memdc mit bitblt geblittetso das ist meine 5 punkte plan zu deiner ondraw
viel erfolg
-
oh man... ein problem nach dem anderen
also danke erstmal für deine hilfe... hab das jetzt über bitblt gemacht, ohne onDraw(...) nochmal aufzurufen.
und endlich hab ich tatsächlich ein halbwegs vernünftiges farbiges bild.doch das bild das ich nun bekomme ist horizontal gespiegelt... ich vermute es liegt daran, dass das ursprungs cdc (das pdc) von unten nach oben schreibt (hab ich nicht selber geschrieben, sondern so bekommen)
gibt es eine möglichkeit, das ganze gleich gespiegelt zu blitten?
oder muss man es danach spiegeln, und wenn das so ist, wie macht man das?mit dem code hab ich's geblittet (ab dem if):
if(pDoc->getCreateBMP() == true) { //to enter the if-area just one time for each file pDoc->setCreateBMP(false); //create a DC for drawing directly in a bitmap CDC memDC; memDC.CreateCompatibleDC(pDC); CRect rcClip, rcClient; pDC->GetClipBox( &rcClip ); GetClientRect(&rcClient); //Select a compatible bitmap into the bitmap DC CBitmap bitmap; bitmap.CreateCompatibleBitmap(pDC, w, h); memDC.SelectObject( &bitmap ); //now drawing into the bitmap memDC.BitBlt( rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), pDC,rcClip.left, rcClip.top, SRCCOPY ); //CImage erstellen CImage image; //Bitmap zuweisen image.Attach(bitmap); image.DIBOR_TOPDOWN; //Bitmap speichern image.Save(L"C:\\test.jpg"); }
gruß
Kleriker
-
und warum stellst du den SetWindowOrg() und SetWindowExt() vor dem Blitten nicht wieder auf 0? sollte doch dann alles wieder normal sein und benötigen tust du das doch so und so nicht mehr
-
das hab ich schon probiert, das bringt nichts...
entweder bekomm ich ein ganz schwarzes bild, oder trotzdem nur spiegelverkehrt...
-
keine andere idee?
-
na dan dreh doch einfach das bild zu fuß oder schau mal bei codeproject.com vorbei, vielleicht findest du ne klasse die das gleich mit kann
-
also per hand umdrehen, kann man schon vergessen... jedenfalls nach der pixel für pixel methode...
ich hab aber das hier gefunden.
da spiegelt einer das bild der funktion render von der klasse IPicture
leider stürzt das prog bei mir während des render-befehls abpIPic->Render(hDC, zeichenflaeche.left, zeichenflaeche.bottom, zeichenflaeche.Width(), -zeichenflaeche.Height(), 0, hmHoehe, hmWeite, -hmHoehe, NULL);
schon mal jemand damit gearbeit und kann mir sagen, ob hier ein fehler drin steckt
und wie man mit der dieser Klasse IPicture umgeht?
-
wieso kannst du das net Pixelweise swapen, du darfst nur net getpixel und setpixel nehmen das wird der unfug elend langsam, aber wenn du dir die rohdaten also das bitmap-array geben lässt dann geht das fix. aber wenn du willst nimm das, is aus net klasse von mir habs etwas umgeschrieben und natürlich net getestet
void FlipPicture(CBitmap &BM,BOOL Horizontal) { BITMAP bm; BM.GetObject(sizeof(BITMAP), (LPSTR)&bm); BYTE *bmpBufferSource = new BYTE[ bm.bmWidthBytes*bm.bmHeight ];//allocate memory for image //byte buffer BYTE *bmpBufferDest = new BYTE[ bm.bmWidthBytes*bm.bmHeight ];//allocate memory for image //byte buffer ULONG dwValue=BM.GetBitmapBits(bm.bmWidthBytes*bm.bmHeight, bmpBufferSource);//Get the bitmap bits //into a structure*/ if(Horizontal == TRUE) { for(LONG Count = 0;Count < bm.bmHeight;Count++) { BYTE *Source = &bmpBufferSource[bm.bmWidthBytes*(Count+1)]; BYTE *Dest = &bmpBufferDest[bm.bmWidthBytes*Count]; __asm { mov ECX,bm.bmWidthBytes; mov EDX,Source; mov EBX,Dest; next: mov EAX,[EDX] mov [EBX],EAX lea EDX,[EDX-4] lea EBX,[EBX+4] sub ECX,4 jnz next } } } else { for(LONG Count = 0;Count < bm.bmHeight;Count++) { BYTE *Source = &bmpBufferSource[bm.bmWidthBytes*(bm.bmHeight-Count-1)]; BYTE *Dest = &bmpBufferDest[bm.bmWidthBytes*Count]; __asm { mov ECX,bm.bmWidthBytes; mov EDX,Source; mov EBX,Dest; next1: mov EAX,[EDX] mov [EBX],EAX lea EDX,[EDX+4] lea EBX,[EBX+4] sub ECX,4 jnz next1 } } } dwValue = BM.SetBitmapBits(bm.bmWidthBytes*bm.bmHeight,bmpBufferDest); delete bmpBufferSource; delete bmpBufferDest; }
wenn das immer noch zu lansam is weiss ich auch net
gruß
-
wow stark... funktionert ohne probleme
recht herzlichen, tief empfundenen, wirklich ernst gemeinten, Vielen Dank