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
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

[/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

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

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