Fastest way to draw 1024x1024 dots on screen - qt

I am developing a program that must calculate a color of each point on a 1024x1024 picture using a special algorithm. The color of a point represents some value. So each point is independent of other points and must be drawn separately. I do not have to refresh the picture too frequently. Actually, I need to display it only once.
What is the fastest approach to drawing separate pixels in Qt?
Can I get some sort of "screen memory" and write all the picture as an array of 4-byte sets, representing each pixel as 4 bytes in that memory?

The QImage class is optimized for pixel manipulation. You can instantiate one with the requred size and then either set the pixels individually setPixel, or access the raw data and manipulate them in place via bits(). Just be sure to use the correct format (e.g. RGBA values or color indices for 8-bit images)

The fastest solution may be to create a QImage, manipulate it (set the pixels) and then get Qt to draw it.
The QImage class is for fast IO, from the manual:
The QImage class provides a hardware-independent image representation that allows direct access to the pixel data, and can be used as a paint device.
The QImage class supports several image formats described by the Format enum. These include monochrome, 8-bit, 32-bit and alpha-blended images which are available in all versions of Qt 4.x.
There is information on pixel manipulation in the Detailed Description section.
To display it the simplest way would be to convert it to a pixmap with QPixmap::fromImage and then put it in a label with QLabel::setPixmap.
For more control, you could sub-class QWidget, overload the paintEvent, and draw the QImage with a QPainter with QPainter::drawImage.

You might try to use an OpenGL widget and the glDrawPixels function.

Related

Display QML rectangles on video stream based on object recognition

I have a video stream as describe in Qt Video Overview, using the MyVideoProducer mechanics. The source images are analyzed and I have a list of connected components (x,y,width,height) and I want overlay rectangles on the video.
Can I do this by sending a list of rectangle co-ordinates to QML and have it place the rectangles or do I need to create my own overlay images?
I looked at the QtQuick particle system but it doesn't seem to fit. Other questions have the layout of the rectangle managed by Qt/Qml, but I need the rectangle to be placed according to the co-ordinates that the vision pipeline has determined in C++ and sent to the QML front-end. They will be stale/related to the video frames.
There is an example, but the overlay is unrelated to the video. I think I need an overlay that is synced to the onNewVideoContentReceived(). QML won't be able to determine how to keep any list of rectangle in sync with the video easily.
I just modified the original buffer creation, debayered from a camera, to draw the rectangles myself in the RGBA format. It avoids the synchronization issue of the video frame with the object location data. I did not use alpha but just replacement of pixels. For my content, the amount of boxes versus the video area was not great. With alpha rectangles and a lot of objects, it may be more efficient to involve a GPU. In fact, you could used fixed size squares and not the CCL bounded region and this might be significantly faster with a GPU.
A QML solution would be more elegant, but this solution works.
Alternative options are QVideoFrame::setMetaData, this can tie the CCL QRect list to the frame, so that the association is clear and tied to the frame. The method onNewVideoContentReceived() of the MyVideoProducer could render the rectangles from C++.
Another option is QAbstractVideoFilter, which will modify the original buffer to add additional data to the images presented. This is easy to enable/disable via the QML front end.
All solutions rely on C++ so it is not easy to change coloring, etc in QML. For example if the object has a recognized property such as 'male', 'female', 'cat', 'vehicle', etc the QML could update the highlighting appropriately and maintain an accounting of the object types.

How to visualize QImage in QML

I have a QAbstractListModel with custom objects as items. Each object has a QImage that is loaded from a database. I use ListView in QML to visualize it but I do not see any mean to represent QImage in the delegate. Image primitive seems to accept only URLs.
Is the only way for me to show QImages is to create a QQuickImageProvider with some custom system of a URL per element (looks like a total overkill)?
I think QQuickImageProvider is the proper way.
Also, I think you can use the word 'overkill' if you know exactly how the Qt internals work. Otherwise it's just guessing.
AFAIK there is a complex caching system of images (and other data) underneath, so once an image pixmap is loaded (and doesn't change) data retrieval is immediate. So no overkill at all, since in any case at some point you need to load those QImage, but just once.
I believe a QQuickImageProvider provides pointers to the cached data, and not the whole rasterized data every time. Moreover blitting operations are nowadays performed with hardware accelerations, so it's a single operation taking a fraction of millisecond.
In other words you end up having:
give me image with url "image://xyz"
Qt looks up in the cache and returns the data pointer or performs a full load of the image if not found
the QML renderer passes the data array to OpenGL
one single blit operation (microseconds) and you have it on screen
A QML ShaderEffect will bind a QImage to a GLSL Sampler2D. See the list of "how properties are mapped to GLSL uniform variables" in the ShaderEffect docs. Needs a few lines of GLSL writing in the ShaderEffect to pass pixels through, (will update this post with an example sometime, when I have access to my code), but the result is a fast, QSG-friendly all-QML element which can render QImages.

Technology of WinHex

I am going to create Win Hex like application in Qt. I want to know which widget should I use for creating hex display area. I have to open hard disk in it so it would be a very large number of lines for displaying 500 GB of disk.
So, which widget can handle this large number of hexadecimal lines?
I have started to do it in QWidget's paint event but the height of QWidget is in integer so number of lines could not be greater than the range of integer.
So, should I use QTextEdit or QPlainTextEdit?
You use wrong way. Consider to use QAbstractItemModel + QTableView. Your model can use "virtual window". It means that your model holds only small piece of data which will be loaded on demand.

QT drawing pixels to graphics scene

I need to write a std::vector< double > values to a qGraphicsScene. (values between 0-1, each element represents a pixel - grayscale)
Later i want to access the pixels of the image for replace the color (i don't have time to replace the whole image)
thx. for the answer!
If you're wanting to do such low level modification, I'd recommend taking a look at the QImage class. Members such as QImage::setPixel will give you access to individual pixels for modification.
If you need this kind of functionality on a QGraphicsScene, then you could draw to the QImage and then convert that to a QPixmap (with QPixmap::convertFromImage) for use with a QGraphicsPixmapItem, and then place the QGraphicsPixmapItem onto the scene.
You may want to take a look at the generic Qt containers, such as QVector as well.

Qt, low cost way to display only part of large QImage

I draw frequency spectrum of WAV file inside QImage (example: http://savepic.net/2350314.jpg). The WAV file may be long enough to not fit into screen considering good time resolution.
I need to be able to srcoll through entire file fast enough, possibly without filesystem reading operations.
So i have to keep large QImage in memory for fast scrolling. Another desigion would be slower, because it would require me to redraw QImage (QImages) every time user scrolls a screen.
Assuming the desigion with keeping large QImage in memory (1024x50000, for example) i must be able to display some part of that large QImage in the program window.
What is the solution with lowest cost? Using QScrollArea or maybe using QPainter method drawImage() with offset arguments?
I would definitely build a small custom widget and reimplement its paint() method with a QPainter (and scrolling with offsets etc).
Using QPixmap for showing the needed parts of the image should be faster then natively drawing (a part of) a QImage.

Resources