Update der Bildausgabe
-
Hallo!
Ich versuche einfach ein unsigned char array als 8bit Bitmap graphisch auszugeben. Ich schaffe es zwar, die Daten aus dem unsigned char array darzustellen, meine Methode erscheint mir aber sehr umständlich und ressourcenfressend, da für jede Ausgabe erneut ein BitmapObjekt angelegt werden muss. Das Wälzen der Hilfe war für mich eher verwirrend als informativ. Jetzt kenne ich ein Dutzend von Varianten wie es gehen müsste, bislang funktioniert aber nur die eine.
void Ausgabe1Frm::CreateBMP(unsigned char *input, int sizeX, int sizeY) { wxImage im = new wxImage(); im->Create(sizeX,sizeY,1); im->SetData(input); wxBitmap bit=new wxBitmap(*im); wxClientDC area=new wxClientDC(this); area->DrawBitmap(*bit,0,0,0); }
Es muss doch die Möglichkeit geben, nach Anlegen der drei Objekte wxImage,wxBitmap und wxClientDC, diese für die neuen Daten(input) zu "refreshen"!?!
Bin für jede Hilfe dankbar,
Thx
-
für wxImage brauchst du da kein new. (und wenn dann auch ein delete).
Gleiches für das Bitmap, wobei das evtl. noch sinnvoll mit new ist.
Insgesamt sollte es dann aber auch eine Membervariable sein.
Und eigentlich könntest du da direkt ein wxStaticBitmap nehmen, statt es in einen DC zu schmeissen (und wenn DC würde ich das über OnPaint regeln).
-
Nun hab ich die Variablen weitestgehend lokal angesetzt, um mir das new und delete zu ersparen. Die ersten beiden Ausgabe funktionieren auch problemlos, erst beim dritten Aufruf schmiert mir das Programm ab.
global: wxImage im; void Ausgabe1Frm::CreateBMP(unsigned char *input, int sizeX, int sizeY) { im.SetData(input); wxBitmap bit(im,-1); wxClientDC area(this); area.DrawBitmap(bit,0,0,0); }
...und wenn DC würde ich das über OnPaint regeln
Besagtes OnPaint finde ich leider weder bei wxPaintDC, wxClientDC, wxWindowDC, wxScreenDC, wxMemoryDC noch bei der Urspungsklasse:wxObject. Bin icke blind?
-
Also ne Globale Variable ist noch schlechter.
Lokal ist schon okay, aber das new kannst du dir da wirklich sparen. Und wenn, delete nicht vergessen.
Würde da aber sowieso ein wxStaticBitmap empfehlen.Für OnPaint schau einfach mal in das Tutorial im Magazin zu wxWidgets.
-
Hi!
Ich bin mir bei wxStaticBitmap unsicher. In der Hilfe heißt es:
"It is meant for display of the small icons in the dialog boxes and is not meant to be a general purpose image display control. In particular, under Windows 9x the size of bitmap is limited to 64*64 pixels and thus you should use your own control if you want to display larger images portably."
Meine Ausgaben sollten aber über bis zu 1024x1024 gehen. Mir scheint wxStaticBitmap deshalb nicht passend zu sein. Oder irre ich mich?
Ich habe derweil meinen code umgeschrieben. Leider hängt sich das Prog immer noch nach xten Ausgabe auf und ich weiss nicht worüber es stolpert. Erstmal mein code:
im.Create(xN,yN,1); imageDat=NULL; //Processes the imagedata void Ausgabe1Frm::SetImag(int sizeX, int sizeY, double *input) { int posIns=0, posOut=0, sizeTmp=sizeX*sizeY; double temp[sizeTmp]; double MAX=INT_MIN, MIN=INT_MAX; imageDat=(unsigned char*) malloc(sizeRGB*sizeof(unsigned char)); [b]//muss mit malloc allokiert werden, so verlangt es wxImage.SetData [/b] //Eingang wird in ein temporäres Feld geschrieben for(int i=0;i<sizeTmp;i++) {temp[i]=input[i];} for(int i=0;i<sizeTmp;i++) //Getting MIN/MAX { if(temp[i]>=MAX) MAX=temp[i]; //Find maximum if(temp[i]<=MIN) MIN=temp[i]; //Find minimum } //wxLogMessage(wxString::Format("MAX: %E \t MIN: %E \n",MAX,MIN)); //wxLogMessage(wxString::Format("MAX: %f \t MIN: %f \n",MAX,MIN)); //Schwellwertfestlegung um konstantes Feld zu erhalten if(fabs(MAX-MIN)<pow(10,-10)) { for(int i=0;i<sizeTmp;i++) {temp[i]=255;} } else { for(int i=0;i<sizeTmp;i++) {temp[i]=(temp[i]-MIN)/(MAX-MIN)*255;} //Normierung[0..255] } for(int y=0;y<yN;y++) //RGB-Mapping, inneres Feld wird in äußeres geschrieben { for(int x=0;x<xN;x++) { posOut=x+y*xN; if(x<sizeX && y<sizeY) { posIns=x+y*sizeX; for(int i=0;i<3;i++) {imageDat[3*posOut+i]=(unsigned char) temp[posIns];} } else { for(int i=0;i<3;i++) {imageDat[3*posOut+i]=0;} } } } [b]im.SetData(imageDat);[/b] } void Ausgabe1Frm::ShowImag() { [b]wxBitmap bit(im); wxClientDC area(this); area.DrawBitmap(bit,0,0,0); //Refresh(); //im.Destroy(); free(imageDat); imageDat=NULL;[/b] }
wxImage und imageDat sind global deklariert:
wxImage im;
unsigned char *imageDat;Ich versteh nicht so recht, was es mit wxImage.create()/setData()/destroy() auf sich hat. Bei setData() heißt es:
The data must have been allocated with malloc(), NOT with operator new. After this call the pointer to the data is owned by the wxImage object, that will be responsible for deleting it.
Warum mit malloc()? Und inwiefern gehört der Zeiger dann zum wxImageObjekt? Ist mein free(imageDat) somit überflüssig? Benötige ich stattdessen destroy() um den allokierten Bereich wieder freizugeben? Wenn ja, warum scheitert dann meine Ausgabe(sie wird nicht mehr aktualisiert)?
Thx
-
Nee, wxStaticBitmap kannste auch darüber hinaus benutzen.
Das ist einfach noch was uraltes was in der Doku steht.Zum rest, naja ka.
Hab sowas noch nicht gemacht, evtl. einfach das free weglassen, steht ja das das von wxImage gemacht wird.
Und das mit der globalen Variable würde ich mal ändern.