Seite 1 von 2

[solved] Array mit Bilddaten als Bild anzeigen lassen

Verfasst: 21. Januar 2008 11:10
von AndiLatte
Ich habe ein Array mit Pixeldaten vorliegen und möchte dies nun auch bildlich sehen können.
An was und vorallem wie übergebe ich das Array an "QT".
Das Example basicdrawing hab ich mir angeschaut komme bekomme die Brücke zum Pixel-Array-Anzeigen aber nicht hin.
Ich bin für jeden Hinweis dankbar!

:(

Verfasst: 21. Januar 2008 11:16
von Christian81
Wie liegen die Daten im Array vor?

Siehe http://doc.trolltech.com/4.3/qimage.html#QImage-6

Verfasst: 21. Januar 2008 12:37
von AndiLatte
Christian81 hat geschrieben:Wie liegen die Daten im Array vor?
Die Daten liegen in 32Bit vor. Sprich ein Array der Größe x*y*4.
Auf den ersten 24Bit liegen die RGB Werte die letzten 8 Bit sind 0.

Verfasst: 21. Januar 2008 12:44
von Christian81
Sieht doch gut aus - da müsste mein Link doch (fast) passen. Ggf. musst Du die bits etwas hin- und herschieben da als format nur ARGB und nicht RGBA unterstützt wird.

Verfasst: 21. Januar 2008 13:29
von AndiLatte
Das

Code: Alles auswählen

QImage::QImage ( const uchar * data, int width, int height, Format format )
steht.

Jetzt muss das doch an eine pixmap übergeben? Oder einen Paintevent?

Verfasst: 21. Januar 2008 13:52
von Volker
Mit QPixmap::fromImage kannst Du aus dem QImage ein QPixmap erzeugen, welches Du zum Beispiel über ein QLabel mit setPixmap anzeigen lassen kannst.

Verfasst: 21. Januar 2008 16:13
von AndiLatte
Es läuft dann leider doch nicht.
Wenn die unten genannte Funktion aufrufe bekomme ich ab

Code: Alles auswählen

QImage video_pixmap(pixels, image->info.size.u, image->info.size.v,  QImage::Format_RGB32);
einen Speicherzugriffsfehler :?

Code: Alles auswählen

	pixmap_video = new QPixmap;
	pixmap_videoLabel = new QLabel;
pixmap_videoLabel->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored);
	pixmap_videoLabel->setBackgroundRole(QPalette::Dark);
	pixmap_videoLabel->setAutoFillBackground(true);
	pixmap_videoLabel->setMinimumWidth(512);
 	pixmap_videoLabel->setMinimumHeight(256);

Code: Alles auswählen

void MainWindow::set_image(image_t* image)
{
unsigned char* pixels;

pixels = new unsigned char [image->info.size.u*image->info.size.v*4];

for (int i = 0; i < image->info.size.u*image->info.size.v; i++)
	{
		unsigned char gv = (unsigned char) (image->data[i]);
		pixels[i*4] = gv;
		pixels[i+1*4] = gv;
		pixels[i+2*4] = gv;
		pixels[i+3*4] = 0;
}

QImage video_pixmap(pixels, image->info.size.u, image->info.size.v,  QImage::Format_RGB32);

QPixmap setPixmap(QPixmap::fromImage(video_pixmap));

}

Verfasst: 21. Januar 2008 17:12
von Volker
Das kann zwar viele Ursachen haben, aber was mir spontan auffällt:

Code: Alles auswählen

pixels = new unsigned char [image->info.size.u*image->info.size.v*4]; 
Wo wird der hier angelegte Speicher wieder freigegeben?

Code: Alles auswählen

for (int i = 0; i < image->info.size.u*image->info.size.v; i++)
   {
      unsigned char gv = (unsigned char) (image->data[i]);
      pixels[i*4] = gv;
      pixels[i+1*4] = gv;
      pixels[i+2*4] = gv;
      pixels[i+3*4] = 0;
} 
Sollte es da nicht eher heißen:

Code: Alles auswählen

for (int i = 0; i < image->info.size.u*image->info.size.v; i++)
   {
      unsigned char gv = (unsigned char) (image->data[i]);
      pixels[i*4] = gv;
      pixels[i*4+1] = gv;
      pixels[i*4+2] = gv;
      pixels[i*4+3] = 0;
} 

Verfasst: 21. Januar 2008 17:33
von AndiLatte
Volker hat geschrieben:Das kann zwar viele Ursachen haben, aber was mir spontan auffällt:

Code: Alles auswählen

pixels = new unsigned char [image->info.size.u*image->info.size.v*4]; 
Wo wird der hier angelegte Speicher wieder freigegeben?

Code: Alles auswählen

if(pixels != 0){delete pixels;}
pixels = new unsigned char [image->info.size.u*image->info.size.v*4]; 
ergibt wohl ne (ehr böse) Fehlermeldung (über die ich dennoch dankbar bin)

Code: Alles auswählen

*** glibc detected *** .............  free() : invalid pointer .... ***

Code: Alles auswählen

pixels = new unsigned char [image->info.size.u*image->info.size.v*4]; delete pixels;
ergibt den Speicherzugrifsfehler wie zuvor




Volker hat geschrieben:

Code: Alles auswählen

for (int i = 0; i < image->info.size.u*image->info.size.v; i++)
   {
      unsigned char gv = (unsigned char) (image->data[i]);
      pixels[i*4] = gv;
      pixels[i+1*4] = gv;
      pixels[i+2*4] = gv;
      pixels[i+3*4] = 0;
} 
Sollte es da nicht eher heißen:

Code: Alles auswählen

for (int i = 0; i < image->info.size.u*image->info.size.v; i++)
   {
      unsigned char gv = (unsigned char) (image->data[i]);
      pixels[i*4] = gv;
      pixels[i*4+1] = gv;
      pixels[i*4+2] = gv;
      pixels[i*4+3] = 0;
} 
Macht Sinn :wink:[/code]

Verfasst: 21. Januar 2008 17:50
von AndiLatte

Code: Alles auswählen

*** glibc detected *** .............  free() : invalid pointer .... ***
/quote]

Ich arbeite mit OpenSuse10.2 und ausser dem Paket glibc-obsolete sind alle glibc Pakete installiert! Leider hat der Rechner auf dem ich programmiere kein Netz Zugang und die Installations CDs sind nicht greifbar :roll:

Verfasst: 22. Januar 2008 09:36
von AndiLatte
der Speicherzugriffsfehler verschwindet, wenn ich anstatt

Code: Alles auswählen

pixels = new unsigned char [image->info.size.u*image->info.size.v*4]; 
QImage video_pixmap([b]pixels[/b], image->info.size.u, image->info.size.v,  QImage::Format_RGB32);
QPixmap setPixmap(QPixmap::fromImage(video_pixmap));  
dies hier schreibe:

Code: Alles auswählen

pixels = new unsigned char [image->info.size.u*image->info.size.v*4]; 
QImage video_pixmap(image->info.size.u, image->info.size.v,  QImage::Format_RGB32);
QPixmap setPixmap(QPixmap::fromImage(video_pixmap));  
Jedoch erscheinen dann natürlich die Pixel nicht auf der Pixmap :roll:

Verfasst: 22. Januar 2008 09:45
von Christian81
Das

Code: Alles auswählen

  int width = 300;
  int height = 200;
  unsigned char *pixels = new unsigned char [width*height*4];
  for (int i = 0; i < width*height; i++)
  {
    unsigned char gv = 0x3f;
    pixels[i*4] = gv;
    pixels[i*4+1] = gv;
    pixels[i*4+2] = gv;
    pixels[i*4+3] = 0;
  }

  QImage video_pixmap(pixels, width, height,  QImage::Format_RGB32);
  QPixmap setPixmap(QPixmap::fromImage(video_pixmap));
  setPixmap.save("temp.png", "PNG"); 
  delete[] pixels;
funktioniert bei mir prima.
Wie gross ist dein Bild?

Verfasst: 22. Januar 2008 09:56
von AndiLatte
Christian81 hat geschrieben:
funktioniert bei mir prima.
Wie gross ist dein Bild?
Das Bild ist 512x256 Pixel was mir eine andere Funktion auch prima ausspuckt

Verfasst: 22. Januar 2008 10:00
von Christian81
Also kein Speicherproblem.
Ggf. hast Du dich mit den sehr sprechenden Variablennamen 'u' und 'v' vermacht - ansonsten ist ja alles richtig - siehe mein Codebeispiel.

Verfasst: 22. Januar 2008 11:43
von ObeliX
AndiLatte hat geschrieben:
Volker hat geschrieben:Das kann zwar viele Ursachen haben, aber was mir spontan auffällt:

Code: Alles auswählen

pixels = new unsigned char [image->info.size.u*image->info.size.v*4]; 
Wo wird der hier angelegte Speicher wieder freigegeben?

Code: Alles auswählen

if(pixels != 0){delete pixels;}
pixels = new unsigned char [image->info.size.u*image->info.size.v*4]; 
ergibt wohl ne (ehr böse) Fehlermeldung (über die ich dennoch dankbar bin)

Code: Alles auswählen

*** glibc detected *** .............  free() : invalid pointer .... ***
deinem posting vom Mo Jan 21, 2008 16:13 ist zu entnehmen, daß pixel ne lokale variable ist. diese vor dem new zu deleten macht nicht nur keinen sinn, es ist richtig gefährlich, denn der compiler ist nicht verpflichtet pointer von sich aus mit NULL zu initialisieren. da löscht du dann sonstwo nen byte weg. und keinen sinn macht es, weil es ne lokalel variable ist. du kannst also nicht den bereich "vom letzten mal" löschen bevor du ihn neu benutzt. und zum dritten löscht man arrays mit delete [] und nicht mit delete !
AndiLatte hat geschrieben:

Code: Alles auswählen

pixels = new unsigned char [image->info.size.u*image->info.size.v*4]; delete pixels;
ergibt den Speicherzugrifsfehler wie zuvor
pixels=new ... direkt gefolgt von einem delete ? ist das nur nen fehler im posting oder steht das so in deinem code ?


gruß Obel