How to save an image from QML Image element?
-
Something like this:
@
class ImageSaver : public QObject
{
Q_OBJECT
public:
explicit ImageSaver(QObject *parent = 0);public slots:
void save(QObject *item, const QString &path);};
void ImageSaver::save(QObject *imageObj, const QString &path)
{
QGraphicsObject item = qobject_cast<QGraphicsObject>(imageObj);if (!item) { qDebug() << "Item is NULL"; return; } QImage img(item->boundingRect().size().toSize(), QImage::Format_RGB32); img.fill(QColor(255, 255, 255).rgb()); QPainter painter(&img); QStyleOptionGraphicsItem styleOption; item->paint(&painter, &styleOption); img.save(path);
}
@And then in QML:
@
import Qt 4.7Rectangle {
width: 640
height: 480
color: "white"Image { id: imgItem fillMode: Image.PreserveAspectFit source: "test.jpg" } MouseArea { anchors.fill: parent onClicked: { imageSaver.save(imgItem, "/home/meego/saved-test.jpg"); } }
}
@with imageSaver is an instance of ImageSaver and set as context property.
Cheers
Phi -
Hi
I'm have a problem with this code. I can't get it to work... When I try to paint the QGraphicsObject onto the QImage, I end up with the color (white in this case) that was filled in the image before the paint job. I'm using the code just as shown above. I would therefore guess that the paint method does not work. Is there any difference between doing this on the Desktop platform or the Symbian platform? Is there anything else that could make my situation different?
@ QGraphicsObject item = qobject_cast<QGraphicsObject>(imageObj);
if (!item) { qDebug() << "Item is NULL"; return false; } QImage img(item->boundingRect().size().toSize(), QImage::Format_RGB32); img.fill(QColor(255, 255, 255).rgb()); QPainter painter(&img); QStyleOptionGraphicsItem styleOption; item->paint(&painter, &styleOption); // Then I add the image to a database, but that should be irrelevant
@
I really, really need some help! ...I'm drawing a complete blank on this one (pun intended).
-
Yay. I figured it out!
The problem was that I was calling this save method when Image.onProgressChanged() fired and Image.progress == 1. This proved however to be before the Image was actually drawn onto the screen. The solution was to call the method when Image.onPaintedGeometryChanged() fired and Image.progress == 1.
-
Hey @ngocketit, thanks a lot! It worked great :)
-
Hi
Little help please. That piece of code probably works on Qt 4.7 but in 5.3 it doesn't. -The problem lays in qobject_cast -ing since it requires the source to inherit QObject, but QML Image is based on QtObject class.-
My bad QtObject inherits QObject but I'm still getting empty object after casting. By debugging the source imageobject seems to be normal QQuickImage object. Any ideas?
Since I'm really inexperienced in Qt c++ part, could anyone help with that problem.
Thanx.
-
For Qt 5 and later, "Canvas":http://qt-project.org/doc/qt-5/qml-qtquick-canvas.html has loadImage(url) and save(filename) functions.
-
wait for QQuickRenderControl
-
Image loading and saving via Canvas:
@import QtQuick 2.2
import QtQuick.Window 2.1Window {
width: imgLoader.sourceSize.width
height: imgLoader.sourceSize.height
visible: true
property string loadUrl: "file://tmp/image.png"
property string saveUrl: "/tmp/i2.png"Canvas { id: root anchors.fill: parent onPaint: { var ctx = getContext("2d") ctx.drawImage(imgLoader, 0, 0) } } MouseArea { anchors.fill: parent onClicked: { if (root.save(saveUrl)) { console.log("save succeeded") } else { console.log("save failed") } } } Image { id: imgLoader visible: false source: loadUrl }
}@
Note that the parameter to Canvas::save() is a filename, not a URL. It fails when "file://tmp/i2.png" is used.
-
Hi
I decided to solve this a bit differently. I created a new QML type (c++ class) that takes in image url (local or remote) and spits out local url. In case of beginning http:// or https:// class checks if image is already downloaded from the remote server and in that case spits the local url right out w/o wasting the precious mobile data bandwidth.And then there a QML component that fills out the Image type source property when the local url is returned from my so called "Caching class". If anybody's interest I can strip it out of my project and put it up to github with decent comments.