How to save an image from QML Image element?
-
wrote on 19 Feb 2011, 13:38 last edited by
Hi everyone. Is there a way to save cached image from Image element?
Thanks in advance.
-
wrote on 19 Feb 2011, 22:20 last edited by
I found this in the doc(QDeclarativeEngine::addImageProvider):
bq. Note that images loaded from a QDeclarativeImageProvider are cached by QPixmapCache, similar to any image loaded by QML.
But how I can get an image from QPixmapCache? It requires Key (in the find function). I tried to use URL as Key, but it failed.
-
wrote on 20 Feb 2011, 11:08 last edited by
There seems to be no direct way to save cached image of an Image element. However, you can make Image element paint on a QImage and then save the QImage to a file.
-
wrote on 20 Feb 2011, 11:43 last edited by
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 -
wrote on 21 Feb 2011, 16:09 last edited by
ngocketit, thanks! It works very nice!
-
wrote on 17 Mar 2011, 12:46 last edited by
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).
-
wrote on 23 Mar 2011, 11:54 last edited by
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.
-
wrote on 25 Oct 2011, 12:53 last edited by
Hi folks,
The snippet works but I am unsure how the path variable works on Symbian?
What drive the image saves to when it says "saved".Is there a way to set a proper folder like e:\folder on symbian^3?
-
wrote on 28 Oct 2011, 19:59 last edited by
Hey @ngocketit, thanks a lot! It worked great :)
-
wrote on 17 Jun 2014, 12:49 last edited by
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.
-
wrote on 17 Jun 2014, 13:09 last edited by
QDeclarativeView *view = new QDeclarativeView();
QPixmap::grabWidget(view).save(outputFile, 0, 100);create view and grab image file in outputFile
-
wrote on 17 Jun 2014, 13:34 last edited by
Sorry, I'm not quite sure how to implement your solution. Also QDeclarativeView isn't used in Qt5 and Pixmap::grapWidget() also depricated.
But thnx anyways :)
-
wrote on 19 Jun 2014, 10:24 last edited by
sorry I am using older version (As per requirement ) I appreciate your reply
-
wrote on 27 Jun 2014, 13:27 last edited by
Hi
Does anybody have an idea why I can't pass the Image object to the save function. The path comes over nicely but "imageObj" pointer in save() function turns out empty?
-
wrote on 28 Jun 2014, 02:52 last edited by
Hi
I also have an empty pointer. I do not know where to look to solve this problem.
-
wrote on 28 Jun 2014, 03:09 last edited by
For Qt 5 and later, "Canvas":http://qt-project.org/doc/qt-5/qml-qtquick-canvas.html has loadImage(url) and save(filename) functions.
-
wrote on 28 Jun 2014, 03:24 last edited by
wait for QQuickRenderControl
-
wrote on 28 Jun 2014, 03:38 last edited by
I tried to use the Canvas, and also I could not save.
I'll try again tomorrow .. -
wrote on 28 Jun 2014, 04:54 last edited by
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.
-
wrote on 28 Jun 2014, 14:21 last edited by
jeremy_k thanks it works great.