diff --git a/src/plugins/directshow/camera/camera.pri b/src/plugins/directshow/camera/camera.pri
index 0e1c1e895279b21b03854786c30335072d274272..3be1acc49d2facfd116b1a8d6415ef740c7aec72 100644
--- a/src/plugins/directshow/camera/camera.pri
+++ b/src/plugins/directshow/camera/camera.pri
@@ -15,7 +15,8 @@ HEADERS += \
     $$PWD/directshowcameraexposurecontrol.h \
     $$PWD/directshowcameracapturedestinationcontrol.h \
     $$PWD/directshowcameracapturebufferformatcontrol.h \
-    $$PWD/directshowcamerazoomcontrol.h
+    $$PWD/directshowcamerazoomcontrol.h \
+    $$PWD/directshowcameraimageencodercontrol.h
 
 SOURCES += \
     $$PWD/dscameraservice.cpp \
@@ -29,7 +30,8 @@ SOURCES += \
     $$PWD/directshowcameraexposurecontrol.cpp \
     $$PWD/directshowcameracapturedestinationcontrol.cpp \
     $$PWD/directshowcameracapturebufferformatcontrol.cpp \
-    $$PWD/directshowcamerazoomcontrol.cpp
+    $$PWD/directshowcamerazoomcontrol.cpp \
+    $$PWD/directshowcameraimageencodercontrol.cpp
 
 *-msvc*:INCLUDEPATH += $$(DXSDK_DIR)/include
 QMAKE_USE += directshow
diff --git a/src/plugins/directshow/camera/directshowcameraimageencodercontrol.cpp b/src/plugins/directshow/camera/directshowcameraimageencodercontrol.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..912f67a2dd73340f8d937b1ac62db1af09247941
--- /dev/null
+++ b/src/plugins/directshow/camera/directshowcameraimageencodercontrol.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "directshowcameraimageencodercontrol.h"
+#include "dscamerasession.h"
+#include <QImageWriter>
+
+QT_BEGIN_NAMESPACE
+
+DirectShowCameraImageEncoderControl::DirectShowCameraImageEncoderControl(DSCameraSession *session)
+    : QImageEncoderControl(session)
+    , m_session(session)
+{
+}
+
+QList<QSize> DirectShowCameraImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const
+{
+    QList<QSize> res;
+    if (!settings.codec().isEmpty() && !supportedImageCodecs().contains(settings.codec(), Qt::CaseInsensitive))
+        return res;
+
+    QList<QSize> resolutions = m_session->supportedResolutions(continuous);
+    QSize r = settings.resolution();
+    if (!r.isValid())
+        return resolutions;
+
+    if (resolutions.contains(r))
+        res << settings.resolution();
+
+    return res;
+}
+
+QStringList DirectShowCameraImageEncoderControl::supportedImageCodecs() const
+{
+    QStringList supportedCodecs;
+    for (const QByteArray &type: QImageWriter::supportedImageFormats()) {
+        supportedCodecs << type;
+    }
+
+    return supportedCodecs;
+}
+
+QString DirectShowCameraImageEncoderControl::imageCodecDescription(const QString &codecName) const
+{
+    Q_UNUSED(codecName);
+    return QString();
+}
+
+QImageEncoderSettings DirectShowCameraImageEncoderControl::imageSettings() const
+{
+    return m_session->imageEncoderSettings();
+}
+
+void DirectShowCameraImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings)
+{
+    m_session->setImageEncoderSettings(settings);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/directshow/camera/directshowcameraimageencodercontrol.h b/src/plugins/directshow/camera/directshowcameraimageencodercontrol.h
new file mode 100644
index 0000000000000000000000000000000000000000..6891bea774ddecf5021bdb260f58f21f2d88311d
--- /dev/null
+++ b/src/plugins/directshow/camera/directshowcameraimageencodercontrol.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DIRECTSHOWCAMERAIMAGEENCODERCONTROL_H
+#define DIRECTSHOWCAMERAIMAGEENCODERCONTROL_H
+
+#include <qimageencodercontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class DSCameraSession;
+class DirectShowCameraImageEncoderControl : public QImageEncoderControl
+{
+    Q_OBJECT
+public:
+    DirectShowCameraImageEncoderControl(DSCameraSession *session);
+
+    QList<QSize> supportedResolutions(
+        const QImageEncoderSettings &settings = QImageEncoderSettings(),
+        bool *continuous = nullptr) const override;
+
+    QStringList supportedImageCodecs() const override;
+    QString imageCodecDescription(const QString &formatName) const override;
+
+    QImageEncoderSettings imageSettings() const override;
+    void setImageSettings(const QImageEncoderSettings &settings) override;
+
+private:
+    DSCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif // DIRECTSHOWCAMERAIMAGEENCODERCONTROL_H
diff --git a/src/plugins/directshow/camera/dscameraservice.cpp b/src/plugins/directshow/camera/dscameraservice.cpp
index a806cabe36e01fef7607902517ea1d7e60561a11..8115ef385fc0a40f682bcdc8cde7789c1fd528c0 100644
--- a/src/plugins/directshow/camera/dscameraservice.cpp
+++ b/src/plugins/directshow/camera/dscameraservice.cpp
@@ -53,6 +53,7 @@
 #include "directshowcameracapturebufferformatcontrol.h"
 #include "directshowvideoprobecontrol.h"
 #include "directshowcamerazoomcontrol.h"
+#include "directshowcameraimageencodercontrol.h"
 
 QT_BEGIN_NAMESPACE
 
@@ -70,6 +71,7 @@ DSCameraService::DSCameraService(QObject *parent):
   , m_captureBufferFormatControl(new DirectShowCameraCaptureBufferFormatControl)
   , m_videoProbeControl(nullptr)
   , m_zoomControl(new DirectShowCameraZoomControl(m_session))
+  , m_imageEncoderControl(new DirectShowCameraImageEncoderControl(m_session))
 {
 }
 
@@ -81,6 +83,7 @@ DSCameraService::~DSCameraService()
     delete m_videoDevice;
     delete m_videoRenderer;
     delete m_imageCapture;
+    delete m_imageEncoderControl;
     delete m_session;
     delete m_exposureControl;
     delete m_captureDestinationControl;
@@ -134,6 +137,9 @@ QMediaControl* DSCameraService::requestControl(const char *name)
     if (qstrcmp(name, QCameraZoomControl_iid) == 0)
         return m_zoomControl;
 
+    if (qstrcmp(name, QImageEncoderControl_iid) == 0)
+        return m_imageEncoderControl;
+
     return 0;
 }
 
diff --git a/src/plugins/directshow/camera/dscameraservice.h b/src/plugins/directshow/camera/dscameraservice.h
index 2e45edcce47327bf84474e3acaa843f38e74c84b..9a8f745f67e7b44c453a46b4f32da6022275822e 100644
--- a/src/plugins/directshow/camera/dscameraservice.h
+++ b/src/plugins/directshow/camera/dscameraservice.h
@@ -57,6 +57,7 @@ class DirectShowCameraCaptureDestinationControl;
 class DirectShowCameraCaptureBufferFormatControl;
 class DirectShowVideoProbeControl;
 class DirectShowCameraZoomControl;
+class DirectShowCameraImageEncoderControl;
 
 class DSCameraService : public QMediaService
 {
@@ -82,6 +83,7 @@ private:
     DirectShowCameraCaptureBufferFormatControl *m_captureBufferFormatControl;
     DirectShowVideoProbeControl *m_videoProbeControl;
     DirectShowCameraZoomControl *m_zoomControl;
+    DirectShowCameraImageEncoderControl *m_imageEncoderControl;
 };
 
 QT_END_NAMESPACE
diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp
index bf81262d602a100ea5f777b63e86ff8905359619..85947c655215a8b3a0329ff398479566b22ca253 100644
--- a/src/plugins/directshow/camera/dscamerasession.cpp
+++ b/src/plugins/directshow/camera/dscamerasession.cpp
@@ -584,10 +584,13 @@ int DSCameraSession::captureImage(const QString &fileName)
         return m_imageIdCounter;
     }
 
+    const QString ext = !m_imageEncoderSettings.codec().isEmpty()
+        ? m_imageEncoderSettings.codec().toLower()
+        : QLatin1String("jpg");
     m_imageCaptureFileName = m_fileNameGenerator.generateFileName(fileName,
                                                          QMediaStorageLocation::Pictures,
                                                          QLatin1String("IMG_"),
-                                                         QLatin1String("jpg"));
+                                                         ext);
 
     updateReadyForCapture();
 
@@ -687,8 +690,9 @@ void DSCameraSession::processCapturedImage(int id,
                                            const QImage &image,
                                            const QString &path)
 {
+    const QString format = m_imageEncoderSettings.codec();
     if (captureDestinations & QCameraImageCapture::CaptureToFile) {
-        if (image.save(path, "JPG")) {
+        if (image.save(path, !format.isEmpty() ? format.toUtf8().constData() : "JPG")) {
             Q_EMIT imageSaved(id, path);
         } else {
             Q_EMIT captureError(id, QCameraImageCapture::ResourceError,
@@ -844,9 +848,11 @@ bool DSCameraSession::configurePreviewFormat()
 {
     // Resolve viewfinder settings
     int settingsIndex = 0;
+    const QSize captureResolution = m_imageEncoderSettings.resolution();
+    const QSize resolution = captureResolution.isValid() ? captureResolution : m_viewfinderSettings.resolution();
     QCameraViewfinderSettings resolvedViewfinderSettings;
     for (const QCameraViewfinderSettings &s : qAsConst(m_supportedViewfinderSettings)) {
-        if ((m_viewfinderSettings.resolution().isEmpty() || m_viewfinderSettings.resolution() == s.resolution())
+        if ((resolution.isEmpty() || resolution == s.resolution())
                 && (qFuzzyIsNull(m_viewfinderSettings.minimumFrameRate()) || qFuzzyCompare((float)m_viewfinderSettings.minimumFrameRate(), (float)s.minimumFrameRate()))
                 && (qFuzzyIsNull(m_viewfinderSettings.maximumFrameRate()) || qFuzzyCompare((float)m_viewfinderSettings.maximumFrameRate(), (float)s.maximumFrameRate()))
                 && (m_viewfinderSettings.pixelFormat() == QVideoFrame::Format_Invalid || m_viewfinderSettings.pixelFormat() == s.pixelFormat())
@@ -1171,4 +1177,23 @@ void DSCameraSession::updateSourceCapabilities()
     updateImageProcessingParametersInfos();
 }
 
+QList<QSize> DSCameraSession::supportedResolutions(bool *continuous) const
+{
+    if (continuous)
+        *continuous = false;
+
+    QList<QSize> res;
+    for (auto &settings : m_supportedViewfinderSettings) {
+        auto size = settings.resolution();
+        if (!res.contains(size))
+            res << size;
+    }
+
+    std::sort(res.begin(), res.end(), [](const QSize &r1, const QSize &r2) {
+        return qlonglong(r1.width()) * r1.height() < qlonglong(r2.width()) * r2.height();
+    });
+
+    return res;
+}
+
 QT_END_NAMESPACE
diff --git a/src/plugins/directshow/camera/dscamerasession.h b/src/plugins/directshow/camera/dscamerasession.h
index ac861ae58c67576d6245a3189a378d4b9fbe0a47..361a0220e56e65541baa7aa9e07f529b3db7185f 100644
--- a/src/plugins/directshow/camera/dscamerasession.h
+++ b/src/plugins/directshow/camera/dscamerasession.h
@@ -51,6 +51,7 @@
 #include <QtMultimedia/qvideosurfaceformat.h>
 #include <QtMultimedia/qcameraimageprocessingcontrol.h>
 #include <QtMultimedia/qcameraimagecapture.h>
+#include <QtMultimedia/qmediaencodersettings.h>
 #include <private/qmediastoragelocation_p.h>
 
 #include <tchar.h>
@@ -129,6 +130,11 @@ public:
     void addVideoProbe(DirectShowVideoProbeControl *probe);
     void removeVideoProbe(DirectShowVideoProbeControl *probe);
 
+    QList<QSize> supportedResolutions(bool *continuous) const;
+    QImageEncoderSettings imageEncoderSettings() const { return m_imageEncoderSettings; }
+    void setImageEncoderSettings(const QImageEncoderSettings &settings)
+    { m_imageEncoderSettings = settings; }
+
 Q_SIGNALS:
     void statusChanged(QCamera::Status);
     void imageExposed(int id);
@@ -217,6 +223,8 @@ private:
     QMutex m_probeMutex;
     DirectShowVideoProbeControl *m_videoProbeControl;
 
+    QImageEncoderSettings m_imageEncoderSettings;
+
     // Internal state
     QCamera::Status m_status;
     QTimer m_deviceLostEventTimer;