SDI oder SFML: Pixel-Array Darstellen

ActiveO2

Ensign
Registriert
Feb. 2009
Beiträge
161
Hallo,

ich suche eine Möglichkeit ein Array mit Bildpixelwerten möglichst schnell darzustellen.
32Bit und 8Bit Farbformate sollten unterstützt werden.
Ich hoffe dass sich hier jemand finden lässt der schon Erfahrung mit SDl oder SFML machen konnte.

Mögliche Ansätze bisher:

SFML:

Code:
char* pImage; // enthält Pixelwerte

// set pImage..

sf::Image img( width, height, reinterpret_cast<sf::Uint8*> (pImage));

bzw.:

Code:
sf::Image img;
int nSize = width * height * bitsProPixel / 8;

sf::Uint8* pCopy = new sf::Uint8[nSize];
memset( pCopy, 0, nSize);
memcpy( pCopy, pImage, nSize);

img.LoadFromPixels( width, height, pCopy);

und:

Code:
sf::Image img( width, height, sf::Color(0,0,0,255));
sf::Color col;

int pix = 0;
for (int y = 0; y < height; y++)
{
    for (int x = 0; x < width; x++)
    {
        col.b = pImage[pix];
        pix++;
        col.g = pImage[pix];
        pix++;
        col.r = pImage[pix];
        pix++;
        col.a = 255;
        pix++;

        img.SetPixel(x, y, col);
     }
}


SDL:

Für SDL habe ich bisher nur SDL_image gefunden. Aber soweit ich weiß unterstützt SDL_image nur bestimmte vorgegebene Formate
(.jpg, .gif, .bmp, ...)


Hoffentlich hat jemand eine Idee.


.
 
Was genau willst du denn mit den Pixeln machen?
"Möglichst schnell darstellen" hast du gesagt. Meinst du damit einfach aufm Schirm zeigen? Also brauchst du ein GUI-Toolkit? Dazu gabs schon zig Diskussionen in diesem Forum.
SDML hab ich zwar noch nie gehört aber das scheint C++ zu sein? Dann würde ich persönlich dir als "möglichst einfach, schnell, einsteigerfreundlich und leichtgewichtig" FLTK empfehlen:
http://www.fltk.org/
Damit kriegt man als GUI-Einsteiger meiner Meinung nach am schnellsten was sichtbares aufn Schirm.

Evtl isses dir schon klar - aber ein Pixel ist auf dem Bildschirm ziemlich klein ^^ Wenn du jetzt ein Bild aus 200 Pixeln hast (also 200x1) wirst du kaum was erkennen können.
Wie viele Pixel werden das denn so? Du könntest jeden Pixel durch ein entsprechend gefärbtes Quadrat darstellen, dessen Kantenlänge mehr als 1 ist, damits besser erkennbar wird


Edit:
"ich suche eine Möglichkeit ein Array mit Bildpixelwerten möglichst schnell darzustellen."

Wieso ist dann eine Einschränkung bei Dateiformaten ne Einschränkung? (SDL) Das klingt bei dir so, als hättest du die Bildpixel schon in deinem Programm zur Verfügung.

Oder brauchst du eine C++ Library die quasi Datenstrukturen zur Verfügung stellt um Pixelhaufen zu verwalten?
Da ist OpenCV sicher eine der populärsten
http://de.wikipedia.org/wiki/Opencv

Die Uni Heidelberg hat auch eine, die äußerst flexibel ist was die unterschiedlichen möglichen Pixeltypen angeht: http://hci.iwr.uni-heidelberg.de/vigra/
Damit kann man auch unübliche Pixel wie "6 Kanal mit je 10 bit" oder ähnliches verwalten wie sie zB Sateliten liefern.

Wenn du bisschen mehr sagst, was du eigtl machen willst kann man da sicher besser Tipps geben
 
Zuletzt bearbeitet:
:D schonmal danke für den Beitrag.

Also nochmal langsam.
Ich habe folgende Daten zu meinem Bild:

char* pImage; // Enthält Bindinformationen (Werte der Pixel) == { 123, 243, 11, 233, 22, 123, ...}
int nWidth = 1280;
int nHeight = 1024;
int nBitsProPixel = 32;

Zahlen stehen nur zu demonstrationszecken da.
Mein Bild hat also bisher kein Format wie .bmp, .png oder Ähnlichem.

Unter Qt konnte ich z.B. folgende Funktion benutzen um mein "Bild" in einem Widget wiederzugeben:

Code:
//QImage
QImage  ( const uchar * data, int width, int height, Format format )

// In meinem Fall also:
QImage img( pImage, nWidth, nHeight, QImage::Format_RGB32);
QLabel* lbl_ViewImage;
lbl->setPixmap(QPixmap::fromImage(img));
et voilá
Bild ist im QLabel.

Ich brauche praktisch eine Klasse, die es mir ermöglicht aus meinen Werten ein "Bild" zu erzeugen (und dies natürlich möglichst schnell).


SDL und SFML wollte ich wegen der Kompatibilität zu Linux und Windows benutzen.
Außerdem war es bisher recht einfach zu bedienen.

Das klingt bei dir so, als hättest du die Bildpixel schon in deinem Programm zur Verfügung.
Du hast's erfasst! ;)
 
Wenn du schon Erfahrung mit QT hast müsste das damit doch gehen? Damit bist du vollständig Plattformunabhängig (*nix / Apple / Windows) und musst nich extra was neues lernen.
FLTK ist auch Plattformunabhängig
Ne ganze Liste mit GUI-Bibliotheken gibts hier:
http://de.wikipedia.org/wiki/Liste_von_GUI-Bibliotheken

Oder gehts darum die Pixel als Bild auf die Festplatte zu schreiben?

Was ist denn das Problem mit der Geschwindigkeit immer.
Wenn es darum geht schnell hintereinander viele Bilder zu zeigen gibts sicher passende Sachen bei OpenCV die dann speziell für Bildfolgen (=Video) gemacht sind.
Ansonsten ist es immer interessant keine lineare Datenstruktur zu verwenden, weil man dann leichter mit einer
http://de.wikipedia.org/wiki/Region_of_Interest
nur den relevanten Teil des Bildes updaten muss (Siehe auch MPEG...)
 
Das Problem ist, dass QImage von Qt zu langsam ist und flackern entsteht.
Daher hab ich mich mir SDL/SFML angeschaut zwecks DirectRenderer/OpenGL.

Ich brauch keine GUI-Bib's. Ich brauche eine Klasse mit der ich meine Bilddaten verarbeiten kann.
 
Zu dem Flackern:
Ich habs mit QT noch nie probiert aber bei anderen Gui-Bibs gibts unterschiedliche Objekte in denen man Zeichnen kann. Welche mit
http://de.wikipedia.org/wiki/Framebuffer
und welche ohne.
Ich hatte auch schonmal das Phänomen des Flackers mit hoher Frequenz (ich hab damals immer die Szene auf nem sichtbaren Gui-Objekt gemalt und wenns fertig war einmal gelöscht und dann aktualisiert gemalt) und konnte das Flackern durch die Verwendung von sogenannter
http://de.wikipedia.org/wiki/Doppelpufferung
abschalten.
(http://de.wikipedia.org/wiki/Dreifachpufferung gibts auch)

Das Prinzip in Kurzform:
Es existieren quasi 2 Buffer in die du deine Pixel malen kannst. Einen, der aktuell gezeigt wird und einen zweiten, den dein Programm bereits im Hintergrund befüllt.
Du zeichnest deine Pixel nicht direkt auf dem sichtbaren "Panel" (oder wie auch immer es bei deiner GUI heißt) sondern in den nicht-sichtbaren Buffer. Das geht WESENTLICH schneller. Wenn du fertig bist gibst du einmal den Befehl die Buffer zu tauschen. Dh man sieht dann den frisch gemalten aktuellen Buffer und der eben noch sichtbare wird jetzt der, in den du wieder neue Pixel malst
Der Wechsel geschieht eben ohne "Flackern".

Üblicherweise wählt man halt ein Panel/Window/Widget/... mit Buffer statt einem ohne, wenn man auf so nem Objekt schnell viel zeichnet.

Du weißt natürlich als einziger, was genau du machen willst - aber für mich hört sich das immernoch so an als ob du GUI-Bibs brauchst. Jede die ich jemals gesehen habe, stellt ja Möglichkeiten zur Verfügung Bilder darzustellen. Das isses doch was du im wesentlichen willst?

"Bilddaten verarbeiten" klingt nach http://de.wikipedia.org/wiki/Bildverarbeitung ?
Das ist dann quasi maschinelles Sehen? Also im Bereich Robotik?
Da wäre dann wie gesagt OpenCV wohl die bekannteste Lösung. Die Vigra aus Heidelberg kann ich auch Empfehlen, wenn man sich einmal reingefunden hat.
Ne Übersicht gibts hier:
http://www.machine-vision.eu/22-0-Bibliotheken+zur+industriellen+Bildverarbeitung.html
 
Nocheinmal ein großes Dankeschön für deinen Einsatz.

Doubble-Buffering habe ich mir schon angeschaut und auf die schnell mit Qt nicht hinbekommen.
Aber ich habe vorübergehend eine Lösung gefunden in Qt (jetzt auch unter Linux) das Bild "flackerfrei" darzustellen.

mit Hilfe von:
Code:
setAttribute(Qt::WA_OpaquePaintEvent);
bewirke ich, dass der Hintergund nicht immer neu gezeichnet wird.
Das ist natürlich nicht die feine Art aber vorübergehend sollte sie reichen.

Bezüglich der "Bildverarbeitung" so habe ich mich wohl falsch ausgedrückt.
Meine Absicht war es, grob gesagt, zu formatieren.
(Bilddaten verarbeiten: Pixelarray + Höhe + Breite + Bits proPixel => .bmp, .png, etc...)

Sollte ich für SDL /SFML mal zufällig auf eine Lösung stoßen werde ich sie natürlich posten.


Bezüglich OpenCV:
Hast du mir da auf die schnelle eine übersichtliche Doku?



.
 
Zuletzt bearbeitet:
http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/index.html
Unter dem Punkt:
"Reading and writing images"
Api-Doku unter:
http://www.cognotics.com/opencv/docs/1.0/ref/opencvref_highgui.htm


Mit der vigra wäre es genau so einfach. Nur:
exportImage(srcImageRange(myPicture), "bla.bmp");
Api-Doku unter:
http://hci.iwr.uni-heidelberg.de/vi...aImpex.html#gc0d255dfc961a601786b1b0798b42935


Edit:
das ganze geht natürlich auch schon direkt von QT aus - für nen writeImageToFile braucht man keine eigene Image-Bib.

Hier steht einiges dazu:
http://lists.trolltech.com/qt-interest/2004-07/msg00835.html
 
Zuletzt bearbeitet:
Zurück
Oben