Qt World Summit: Register Today!

QML: how to upload a photo from Camera to a web server using XMLHttpRequest

  • Hi,

    I'm using Qt 5.3 to build my first QML app.
    I have a Qt Quick application which takes a photo using Camera, from the QtMultimedia module.
    I would like to upload this image on a web server using XMLHttpRequest, through a POST request. The API I have to use requires multi-part mime header.
    How can I do that? Is it possible to build this request using QML only or do I need a bit of C++?

    My image is stored in an Image type (I can display it, it works) :
    @Image {
    id: photo

    My upload function looks like this, but is incomplete at the moment:
    @function uploadImage(server, callback) {
    var req = new XMLHttpRequest();
    req.onreadystatechange = function() {
    if (req.readyState == XMLHttpRequest.HEADERS_RECEIVED) {
    console.log("Debug: header: " + req.getAllResponseHeaders ());
    } else if (req.readyState == XMLHttpRequest.DONE) {
    console.log("Debug: xml response: " + req.responseText);

        req.open("POST", server + "/api/cAddImage");
        // here I don't know to to build the request to send 'photo'???

    Thanks in advance,
    Best regards

  • Lifetime Qt Champion

  • Thank you for your answer.

    I found this post before and it works to send text data.
    E.g. , here is my code to send credentials to log on the server:

    @req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    req.send("username=" + username + "&password=" + password);@

    But I cannot find the right syntax to send an image???

  • Moderators

    May be using FormData. Never tried though.

  • Here is my solution: image uploading is performed by a separate C++ class, using QNetworkAccessManager:

    @#ifndef IMAGEUPLOADER_H

    #include <QDebug>
    #include <QFile>
    #include <QFileInfo>
    #include <QHttpMultiPart>
    #include <QNetworkAccessManager>
    #include <QNetworkReply>
    #include <QNetworkRequest>
    #include <QString>

    class ImageUploader: public QObject {

    ImageUploader(QObject* parent = 0)
    : QObject (parent)
    , m_networkAccessManager(NULL)
    , m_networkReply (NULL) {
    m_networkAccessManager = new QNetworkAccessManager(this);

    public slots:
    void uploadImage(const QString& imageFilename) {
    QFileInfo fileInfo(imageFilename);
    QFile* file = new QFile(imageFilename);
    if (!file->open(QIODevice::ReadWrite)) {
    emit imageUploaded(999, "Image not found");

        emit imageUploaded(-1, "Try to upload image to server, please wait...");
        QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
        QHttpPart imagePart;
        imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
        imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(QString("form-data; name=\"image\"; filename=\"%1\"").arg(fileInfo.fileName()).toLatin1()));
        QNetworkRequest request("http://www.myserver.com/uploadImage");
        m_networkReply = m_networkAccessManager->post(request, multiPart);
        connect(m_networkReply, SIGNAL(finished()), this, SLOT(uploadImageFinished()));

    private slots:
    void uploadImageFinished() {
    QString xmlReply = QString(m_networkReply->readAll());
    delete m_networkReply;
    qDebug() << xmlReply;
    // here, you can parse the reply from the server...
    emit imageUploaded(0, "Image successfully uploaded");

    // errorCode = -1 : start image uploading
    // 0 : success
    // >0: error
    void imageUploaded(int errorCode, const QString& errorMessage);

    QNetworkAccessManager* m_networkAccessManager;
    QNetworkReply* m_networkReply;

    #endif // IMAGEUPLOADER_H

    To access the "image uploader" object from QML, we need to perform the binding, for example, in the main...

    @#include <QApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    #include "ImageUploader.h"

    int main(int argc, char* argv[])
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;
    ImageUploader imageUploader;
    engine.rootContext()->setContextProperty("imageUploader", &imageUploader);
    return app.exec();


    Finally, uploadImage() method is directly used in the QML code which can also retrieve signal emitted by the C++ code. Something like that...

    @import QtQuick 2.0
    import QtMultimedia 5.3

    Rectangle {
    id: pageCapture

    Connections { // to receive "imageUploaded" signal from the C++ code
        target: imageUploader 
        onImageUploaded: {
            console.log("onImageUploaded: errorCode=" + errorCode + " errorMessage=" + errorMessage);
    Camera {
        id: camera 
        imageCapture {
            onImageSaved: {
                // call the C++ method to upload image (filename is 'path')
    VideoOutput {
        id: videoOutput
        source: camera
        anchors.fill: parent
        focus : visible
        fillMode: VideoOutput.PreserveAspectCrop


  • I can not get the code to work. Maybe the code of uploadimage.cpp is missing? Anybody can help me? Thanks in advance

  • I can not get the code to work. Maybe the code of uploadimage.cpp is missing? Anybody can help me? Thanks in advance

Log in to reply