QImage loadfromData



  • Hallo Zusammen,

    ich versuche einen Screenshot von einen Osciloscope aufzunehmen und in einen GUI darzustellen.
    folgende habe ich versucht:

    QByteArray hilfsVariable = VisaAgilent::instance()->getScreenshot(); // Object von dem Oscilloscope
    
    if (_img_l.loadFromData(hilfsVariable,"BMP"))
    	{
    		ui.labImage->setPixmap(QPixmap::fromImage(_img_l));
    	}
    // es ist immer false
    

    Was mich auch gewundert hat, dass es schon funktioniert hat aber dann plötzlich nicht mehr warum weiss ich nicht.

    Das Screenshot wird immer aufgenommen, das habe ich kontrolliert in dem der Länge der Buffer stets gelesen wird.

    qDebug() << hilfsVariable.size();
    

    Ich zeiger eigentlich der Länger der Buffer in GUI.
    Also problem liegt an diese Funktion:

    _img_l.loadFromData(....);
    

    Was mache ich denn falsch?

    Danke



  • Hi,

    hast du dir mal angeschaut, was in "hilfsVariable" drin steht? Liegen die Daten tatsächlich als BMP Datei vor?

    Versuch doch mal:

    _img_l.loadFromData(hilfsVariable)
    

    Dann schaut QT sich den Header an und versucht die Daten passend zu interpretieren.



  • Schlangenmensch schrieb:

    Hi,

    hast du dir mal angeschaut, was in "hilfsVariable" drin steht?

    Ja

    Schlangenmensch schrieb:

    Liegen die Daten tatsächlich als BMP Datei vor?

    Ja

    Schlangenmensch schrieb:

    Versuch doch mal:

    _img_l.loadFromData(hilfsVariable)
    

    Dann schaut QT sich den Header an und versucht die Daten passend zu interpretieren.

    Das habe ich auch versucht aber es hat leider auch nichts gebracht.

    Was mir eigentlich stört: Manchmal geht und dann wieder nicht ...



  • Ich würde dir empfehlen die Daten die in deinem QByteArray drin stehen mal zu vergleichen, wenns funktioniert und wenn es nicht funktioniert. Ich würde darauf tippen, dass die getScreenshot Funktion nicht immer saubere Werte zurück liefert.

    Ich kann mir vorstellen, dass das Oszilloskop zwischendurch NULL oder NaN Werte liefert und du dann in deinem ByteArray eben Werte drin stehen hast, mit denen QImage nicht klar kommt.



  • Guten Morgen,

    ich habe die Daten der

    hilfsVariable
    

    im Fall wenn es funktioniert und im Fall wenn es nicht funktiniert verglichen.
    Ich kann leider keinen unterschied.
    Die Daten sehen gleich aus und zwar so in der Form: BM(
    Also ich sehe ehrlich gesagt keinen unterschied.



  • Bei genauere Betrachtung habe ich festgestellt, dass die Daten bei der beiden Fälle anders aussehen.

    @Schlangenmensch
    Du hast vollkommen recht in dieses Zusammenhang " die getScreenshot Funktion nicht immer saubere Werte zurück liefert"

    Dafür danke ich dir



  • Ich bin immer noch am gleichen Probem und weiss ich ehrlich gesagt was ist dann falsch in meine Implementierung:

    In diesem Codeabschnitt wird einen Commandos zu den Oscilloscope geschickt, der darauf antwortet.
    Die Implemetierueng sieht so aus:

    int VisaAgilent::writeQuery(const QString &qCommand)
    {
    	ViStatus status;
    	QString command;
    	QByteArray qBaCommand;
    	char viCommand[256];
    	char* viCommandUC;
    	int writeCount;
    	ViChar desc[256];
    
    	command = qCommand + "\n";
    	qBaCommand = command.toLatin1();
    
    	strcpy_s(viCommand, qBaCommand.constData());
    	viCommandUC = (char *)viCommand;
    	char outputBuffer[256];
    	status = viPrintf(_instr, viCommandUC);
    	if (status < VI_SUCCESS)
    	{
    		viStatusDesc(_instr, status, desc);
    		_statusMsg = QString("Error ViPrintf to the device: %1").arg(desc);
    		setMessage(_statusMsg);
    		emit statusUpdate(_statusMsg);
    		return -1;
    	}
    	else
    	{
    		status = viScanf(_instr, "%#b\n", &writeCount, _buffer);
    		if (status < VI_SUCCESS)
    		{
    			viStatusDesc(_instr, status, desc);
    			_statusMsg = QString("Error viScanf to the device: %1").arg(desc);
    			setMessage(_statusMsg);
    			emit statusUpdate(_statusMsg);
    			return -1;
    		}
    		_statusMsg = QString("viScanf completed with %1 characters read").arg(writeCount);
    		setMessage(_statusMsg);
    		emit statusUpdate(_statusMsg);
    		setScreenshot(QByteArray(_buffer, writeCount));
    		return VI_SUCCESS;
    	}
    }
    

    Ist alles Okay wird den _buffen in

    setScreenshot(QByteArray(_buffer, writeCount));
    

    gesetzt und mit einen Get der Inhalt gelesen.

    Den _buffer ist in der Konstruktor so initialisiert

    _buffer[BUF_SIZE] = NULL;
    

    BUF_SIZE ist so definiert:
    #define BUF_SIZE 5000000

    Was mir aufgefallen ist, dass der _buffer nicht Sinnvolle Daten beinhaltet und deswegen kann die

    loadFromData(...)
    

    mit der Daten nichts anfangen.

    Danke in voraus



  • Hallo,

    Problem ist mittlerweile fixiert.
    Es lag daran, dass es bei diese Funktionaufruf:

    status = viScanf(_instr, "%#b\n", &writeCount, _buffer);
    

    folgende nötig:
    Die Länge der

    writeCount
    

    muss in voraus bekannt sein, sonst wird der _buffer bis zu Länger der Query überschrieben (in meinem Fall habe ich die Länge der _buffer genommen) und der Rest der _buffer bleibt mit alten Daten(Initialisierungsdaten)gefühlt.

    Ich verstehe zwar immer noch nicht warum es manchmal funktioniert und wieder nicht aber wie gesagt jetzt geht einwandfrei. 🙂



  • Schön, dass dein Programm jetzt läuft, aber du hast da trotzdem noch Fehler drin!

    Du initialisierst deinen Buffer falsch. Daher hast du keine Ahnung, was in deinem Buffer sonst so drin steht, wenn die Daten nicht überschrieben werden.

    mit

    _buffer[max_size]=NULL;
    

    setzt du den Buffer an der Stelle max_size auf NULL. Das ist auf mehrere Art und Weise schlecht. Zum einen gehört max_size nicht mehr zu deinem Array, daher steht da irgendwas. Wenn du Pech hast, gehört dir der Speicherbereich gar nicht und dein Program verabschiedet sich.
    Außerdem, nehm zur initialisierung die Zahl "0". NULL ist zwar

    "an integral constant expression rvalue of integer type that evaluates to zero"

    aber zumindest ich lese es als Null Pointer und du willst an der Stelle ja wirklich die Zahl 0 haben.

    Eine Array Initialisierung mit 0 sieht zum Beispiel so aus:

    int a[3] = {0};
    

    Die geschweiften Klammern sind hier wichtig. Wenn man das Array im Konstruktor initalisieren will, kann das zum Beispiel so aussehen:

    class Foo {
    public:
      Foo() :_a{ 0 } {};
      int _a[3];
    
    };
    

    Auch hier sind die geschweiften Klammern wichtig.



  • Hi,

    vielen dank


Anmelden zum Antworten