What's the fastest way to show JPG/JPEG images
-
@mrjj Yes, i have an .exe and my main Qt program call this .exe with startDetached().
This .exe file saves each frame to a directory. I want to show each frame with QLabel and after showed in QLabel, delete. I did this but it's slow, it shows frames very slow. -
You could probably use QtMultimedia module for this (with https://doc.qt.io/qt-5/qvideoframe.html class).
How do you show/delete your image? How do you read the image? To avoid unnecessary repaints, try deleting the frame only after a new one has been displayed. Then QLabel does not go through show - hide - show cycle.
Also, try moving the image reading and deleting code to a thread. Perhaps your hard drive IO is responsible.
Lastly, if you can, try steaming the frames from your video source directly to your app.
-
@R_Irudezu
I'm assuming, you usesetPixmap
to asign the Label the modfied fram ?I would probably go with subclassing QWidget and overwriting paintEvent, and drawing the Pixmap directly with QPainter and drawPixmap.
should be faster. Also calling update() after getting the new pixmap should encourage a redraw.
-
Also reading the additonal information you profided,
Creating a new QImage/QPixmap via QImage("filepath") is horribly expensive. Holding a Image/Pixmap in memory and changing the bytes, read via QFile; Should be a good bit faster.
-
@sierdzio I will post my code here:
void MainWindow::showFrames() { QDirIterator it("/framesPath", QDirIterator::Subdirectories); it.next(); // Pass first.. it.next(); // .. two dots QString nextFirstFile = it.next(); QImage Img; Img.load(nextFirstFile); Img = Img.scaledToWidth(ui->QLabel1->width(), Qt::SmoothTransformation); ui->QLabel1->setPixmap(QPixmap::fromImage(Img)); QFile imgFile(nextFirstFile ); imgFile.remove(); }
The timer in constructor:
frameTimer = new QTimer(this); connect(frameTimer, SIGNAL(timeout()), this, SLOT(showFrames())); frameTimer->start(35); frameTimer->setInterval(45);
I don't know my approach is good or not, i need your help.
@sierdzio as you say:
"Lastly, if you can, try steaming the frames from your video source directly to your app."I said "I have to do it in this way. Because i'm manipulating frames with another program."
@J-Hilk
Dear J.Hilk, i've posted code how i'm trying to do. Maybe you can show me a little code example. -
@R_Irudezu No need to create QFile instance to delete a file, use http://doc.qt.io/qt-5/qfile.html#remove-1 instead.
Use QDir::NoDotAndDotDot in QDirIterator it("/framesPath", QDirIterator::Subdirectories); and remove these two it.next().
I'm not sure why you create a QImage first and then QPixmap. You can scale QPixmap as well: http://doc.qt.io/qt-5/qpixmap.html#scaled -
@R_Irudezu said in What's the most efficient way to use QLabel as video player:
I said "I have to do it in this way. Because i'm manipulating frames with another program."
Yes, but perhaps that other program supports sending the data through a pipe. Or you have some influence on that program and can request streaming support to be added. Et cetera
-
this is of course untested. And as the comment says, you have to modfy the QbyteArray to actually get the rgb(a) values you want. You'll have too look that one up. Also the memberImage needs to have the same size as the images you want to load.
void myWidget::showFrames() { QDirIterator it("/framesPath", QDir::NoDotAndDotDot, QDirIterator::Subdirectories); memberQFile.setFileName(it.next()); if(memberQFile.exists() && memberQFile.open(QIODevice::ReadOnly)){ QByteArray data = memberQFile.readAll(); //This will fail, the QByteArray has to be trimmed/changed according to img file/header memcpy(memberImage.bits(),data.data(), data.size()); memberQFile.remove();//Also automatically closes the file update();//request repaint } } void myWidget::paintEvent(QPaintEvent *event) { QWidget::paintEvent(event); QPainter p(this); p.drawImage(rect(),memberImage, memberImage.rect()); }
-
There are no efficient way with QLabel.
-
Hi,
Jpeg decompression is expensive. What size are you images ? What quality ? And to what application are you going to send them ?
You might want to consider using turbo-jpeg to handle the decompression.
-
@SGaist I'm receiving jpeg data and decoding it with GDI+ in quality of between 30-50 (with a native c++ compiled .exe file)
long quality = 50; encoderParameters.Parameter[0].Value = &quality;
All images save under a directory. I don't want to use any other decompress handling. Images are about 30-50 Kb and i just want to show them in a Qt item. (QLabel is very useless for this). All images will be shown with a QTimer (40 ms) and will be deleted.
-
Where are you getting these images from in the first place ?
-
@SGaist I'm getting images from a .exe program written in C. The C program connects a camera, getting images, manipulate them with GDI+ and save them under a specific directory. The program uses some libraries, these libraries are not compatible with any of Qt versions.
-
Why are they not ?