wxWidgets: Pixeldaten anzeigen
-
Hallo!
Ich bearbeite in meinem Programm Graphiken.
Nun möchte ich die Graphik auch während der Bearbeitung schon anzeigen.
Dazu zeichne ich in der Paint Routine in den wxPaintDC.
Was mir dabei nicht gefällt: Ich muss zuerst meine Daten in ein Array mit den Pixelwerten reinstopfen, dann erstelle ich daraus ein wxImage, daraus dann ein wxBitmap, und dieses zeichne ich schließlich in den wxPaintDC. Das kanns ja nicht sein...Die Performance ist trotzdem ganz akzeptabel, aber ich würde das ganze trotzdem gern etwas kürzer schreiben.
Klar kann selbst noch optimieren, indem ich wxImage und wxBitmap nur dann erstelle, wenn sich auch meine eigenes Bildobjekt CImage img geändert hat, und ich in der Paintfunktion nur das Bitmap in den PaintDC zeichne.
Das werde ich jetzt auch gleich machen.
Aber mir gehts vor allem um das Wegoptimieren der "langen" Kette CImage->wxImage->wxBitmap->wxPaintDC.// in der hpp: wxBitmap bmp; wxImage wxImg; CImage img; // meine eigene Klasse // ... // in der cpp: void CWxFrame::OnPaint(wxPaintEvent &event) { // DC holen wxPaintDC dc(this); PrepareDC(dc); // Pixel Array mit malloc allokieren, free wird durch wxImage aufgerufen Byte_t* data = (Byte_t*) malloc(sizeof(Byte_t)*img->GetHeight()*img->GetWidth()*3); // Pixeldaten aus meiner Bildklasse in das Pixelarray schreiben: RGBRGBRGB... for(uint32_t y=0;y<img->GetHeight();++y) { for(uint32_t x=0;x<img->GetWidth();++x) { Pixel& px=img->PixelAt(x,y); if(!px.isGray) { data[(y*img->GetWidth()+x)*3]=px.red; data[(y*img->GetWidth()+x)*3+1]=px.green; data[(y*img->GetWidth()+x)*3+2]=px.blue; } else { data[(y*img->GetWidth()+x)*3]=px.gray; data[(y*img->GetWidth()+x)*3+1]=px.gray; data[(y*img->GetWidth()+x)*3+2]=px.gray; } } } // wxImage->wxBitmap->wxPaintDC: geht das nicht kürzer??? wxImg= wxImage(img->GetWidth(),img->GetHeight(), data); bmp=wxBitmap(wxImg); dc.DrawBitmap(bmp,200,0,false); }
-
Hier nochmal die etwas überarbeitete Paint Funktion, sollte jetzt etwas klarer sein:
void CWxFrame::OnPaint(wxPaintEvent &event) { wxPaintDC dc(this); PrepareDC(dc); const int colors = 3; const int offsetRed = 0; const int offsetGreen = 1; const int offsetBlue = 2; const wxPoint paintPos(200,0); Byte_t* data = 0; if(repaintNeeded) { repaintNeeded = false; data = reinterpret_cast<Byte_t*>(malloc(sizeof(Byte_t)*img->GetHeight()*img->GetWidth()*colors)); for(uint32_t y = 0; y<img->GetHeight(); ++y) { for(uint32_t x=0; x<img->GetWidth(); ++x) { Pixel& px = img->PixelAt(x,y); const int idx = (y*img->GetWidth()+x)*colors; if(!px.isGray) { data[idx+offsetRed]=px.red; data[idx+offsetGreen]=px.green; data[idx+offsetBlue]=px.blue; } else { data[idx+offsetRed]=px.gray; data[idx+offsetGreen]=px.gray; data[idx+offsetBlue]=px.gray; } } } wxImg= wxImage(img->GetWidth(),img->GetHeight(), data); bmp=wxBitmap(wxImg); } dc.DrawBitmap(bmp,paintPos.x,paintPos.y,false); }