In my program, user choice and load an image into QPixmap in some class and after some works on loaded QPixmap the QPixmap passed into an other class, in new class I want to save the passed QPixmap as file, but I don't know what's the QPixmap format!
How we can get image file format from QPixmap?
A pixmap is conceptually system-specific, has no format per se, and may well lose data from the image that you've loaded. Also note that the image format and file format are two different things.
To preserve the image format, you must use the QImage class.
To preserve the file format, you must explicitly use QImageReader to read the image. The file format is available through the reader's format() method. It needs to be stored separately from the image, and used when saving the image later.
Finally, you might wish to preserve the file's name.
As a matter of implementation detail, with the default Qt's raster backend, a QPixmap is a thin wrapper around QImage. But your intent is that of an image, not a pixmap, thus you should use the image class.
QImage img = pixmap.toImage();
img.save("/media/mmcblk0p1/xx.jpeg");
Related
I will get raw video data from the V4L2 driver using VIDIOC_DQBUF, I wanted to render this frame in qt using QVideoFrame(which construct video frame) and QLabel/QPaint(for rendering a video frame).
QVideoFrame::QVideoFrame(QAbstractVideoBuffer *buffer, const QSize &size, QVideoFrame::PixelFormat format)
Constructs a video frame from a buffer with the given pixel format and size in pixels.
Qvideoframe from Qt
As of now, I’m using QImage to rendering RGB24 and QImage supports the only RGB format. However raw video frame which is received from VIDIOC_DQBUF is having different color formats and QVideoFrame support most of them.
Queries:
How to use QVideoFrame::QVideoFrame(QAbstractVideoBuffer *buffer, const QSize &size, QVideoFrame::PixelFormat format) for v4l2 buffer ?
How I can use map(), bits() and mappedBytes() function so that, I can get QVideoFrame constructed for given raw video data?
How I can use QPaint/QLabel to render QVideoFrame?
Regards,
Kulakrni
Lets reverse the order.
How I can use QPaint/QLabel to render QVideoFrame?
You can not. You need to use a QAbstractVideoSurface() derived class. In QML, this is VideoOutput. If you want a single image, then QVideoFrame is not the correct class to use for QPaint/QLabel.
How I can use map(), bits() and mappedBytes() function so that, I can get QVideoFrame constructed for given raw video data?
These functions are your interface to the QAbstractVideoSurface. It depends on how you want to store the VL4 buffer. Are you copying/translating it or are you mapping it directly; then there are ownership issues which this API attempts to address.
How to use QVideoFrame::QVideoFrame(QAbstractVideoBuffer *buffer, const QSize &size, QVideoFrame::PixelFormat format) for v4l2 buffer
You need to sub-class a QAbstractVideoBuffer by either copying/translating the data and keeping it with the class or provide a reference if you are using zero-copy of some sort.
By default, QML Camera and QCamera will find and use /dev/videoX which is a v4l device, via GStreamer. This class should already do the right thing to supply a VideoOutput widget.
See: Qt Video overview
I have a requirement to read pixel values from the picture displayed on the GraphicScene layout. How can I display image using QImage without using pixmap in Qt so that I am able to read the pixel values?
On most platforms, a QPixmap is a thin wrapper around a QImage. The conversions between the two are cheap - especially the pixmap-to-image conversion. Thus, you can use the QGraphicsPixmapItem and use item->pixmap().toImage() without much worry. To confirm that QPixmap is indeed a wrapper, the following check will do:
bool isPixmapThin(const QPixmap &pix) {
auto const a = pix.toImage();
auto const b = pix.toImage();
return a.bits() == b.bits();
}
In all cases, ensure that the image you take from the pixmap won't detach, i.e. always make it const (as in the code example above).
Looking at the documentation of Qt5 it seems possible to change the pixel format of the camera. I need to create a QCameraViewfinderSettings set the new pixel format and set the new settings to the camera... like in this example
QCameraViewfinderSettings viewfinderSettings;
viewfinderSettings.setPixelFormat(QVideoFrame::Format_RGB32);
camera->setViewfinderSettings(viewfinderSettings);
But I cannot find anything similar in QML... Is there any way to do the something in QML? I'd like something like:
Camera {
id: camera
viewfinder.pixelFormat = VideoFrame.Format_RGB32
}
If QML doesn't allow me to set the pixel format what alternatives have I?
No, you can't change the pixel format in QML per the maintainer of that component, but you can pass the QML object to C++ and do it from there per bug report 42909.
As Yoann Lopes wrote in that bug's comments, you can access the QCamera of the QML object with:
QCamera *cam = qvariant_cast<QCamera*>(obj->property("mediaObject"))
How to clear or clean up a QIMage
Following method of mine get a const reference to a QIMage.
MyMethod(const QImage & img) {
// save it to a file
img.save("/path/to/save/the/qimage");
// now I want to clan up img from memory. How should I do it?
}
Question:
How should I clean up the QImage object from memory after use?
Note:
Note that it is a const & QImage. So, answer would involve casting the QImage into non-const?
Also, I am looking at trying to get a QImageData pointer to the data & delete it. Not sure if that is the correct approach here. Do suggest.
You need a non-const reference or a pointer. With a pointer the answer is obvious. With a reference you just assign a default-constructed QImage to it.
MyMethod(QImage & img) {
img.save("/path/to/save/the/qimage");
img = QImage();
}
However, this may still not clean up the memory occupied by the image, if there are additional QImage instances referencing that same image. To overcome this hurdle you need to avoid multiple QImage instances referencing the same image. A Qimage instance is like a shared pointer in this regard.
A const-cast would be considered to reveal a design flaw in your case. I'd recommend against it.
I create a drag object from a QListWidgetItem.
I can send text as mime data in this drag object.
How can I send a pixmap and retrieve it from the mime data?
Would it even be possible to create a QGraphicsItem and retrieve it?
I try to drag & drop from the QListWidget into a QGraphicsView.
There are multiple ways to send a QPixmap through QMimeData:
by encoding it into a file format such as PNG and sending that with mime-type image/png (QMimeData has built-in support for that, cf. QMimeData::imageData()).
by serialising the QPixmap into a QByteArray using a QDataStream and sending the serialisation under an app-specific mime-type application/x-app-name.
by writing the image data to a file on disk and sending a file-URL for it with mime-type text/uri-list (QMimeData has built-in support for this, cf. QMimeData::urls()). This allows to drag these images onto a file manager or the desktop.
similar to (2) above, you can also create a QGraphicsItem, stuff its address into a QByteArray and send that under an app-specific mime-type. This doesn't work if the drag ends in another process, of course (the receiving site can test, because QDragEvent::source() returns 0 in that case), and it requires special care to handle the graphic item's lifetime.
Seeing as QMimeData allows you to pass several formats at once, these options are non-exclusive. You should, however, sort the formats you return from your reimplementation of QMimeData::formats() in order of decreasing specificity, i.e. your app-private formats come first, and text/uri-list comes last.