diff --git a/src/app/commoncomponents/DataTransferMessageDelegate.qml b/src/app/commoncomponents/DataTransferMessageDelegate.qml
index 56ba7607d8e859cd6a0f7293d6bbab85df31efd2..b3a5b2acb73de0c596efee90d3d418885faafc08 100644
--- a/src/app/commoncomponents/DataTransferMessageDelegate.qml
+++ b/src/app/commoncomponents/DataTransferMessageDelegate.qml
@@ -331,23 +331,30 @@ Loader {
                             id: img
 
                             anchors.right: isOutgoing ? parent.right : undefined
-                            property real minSize: 192
-                            property real maxSize: 256
                             cache: true
-                            fillMode: Image.PreserveAspectCrop
+                            fillMode: Image.PreserveAspectFit
                             mipmap: true
                             antialiasing: true
                             autoTransform: true
                             asynchronous: true
-                            sourceSize.width: width
-                            sourceSize.height: height
-                            source: "file:///" + Body
-                            property real aspectRatio: implicitWidth / implicitHeight
-                            property real adjustedWidth: Math.min(maxSize,
-                                                                  Math.max(minSize,
-                                                                           innerContent.width - senderMargin))
-                            width: adjustedWidth
-                            height: Math.ceil(adjustedWidth / aspectRatio)
+                            source: Body !== undefined ? "file:///" + Body : ''
+
+                            // The sourceSize represents the maximum source dimensions.
+                            // This should not be a dynamic binding, as property changes
+                            // (resizing the chat view) here will trigger a reload of the image.
+                            sourceSize: Qt.size(256, 256)
+
+                            // Now we setup bindings for the destination image component size.
+                            // This based on the width available (width of the chat view), and
+                            // a restriction on the height.
+                            readonly property real aspectRatio: paintedWidth / paintedHeight
+                            readonly property real idealWidth: innerContent.width - senderMargin
+                            onStatusChanged: {
+                                if (status == Image.Ready && aspectRatio) {
+                                    height = Qt.binding(() => JamiQmlUtils.clamp(idealWidth / aspectRatio, 64, 256))
+                                    width = Qt.binding(() => height * aspectRatio)
+                                }
+                            }
 
                             Rectangle {
                                 color: JamiTheme.previewImageBackgroundColor
diff --git a/src/app/constant/JamiQmlUtils.qml b/src/app/constant/JamiQmlUtils.qml
index 2eaa6b8c656f00563dd73460d1bbfd9654523e99..9b6128379f53bfb810d74aa3bbaa1be7116d4fec 100644
--- a/src/app/constant/JamiQmlUtils.qml
+++ b/src/app/constant/JamiQmlUtils.qml
@@ -76,4 +76,8 @@ Item {
 
         return Qt.size(globalTextMetrics.contentWidth, globalTextMetrics.contentHeight)
     }
+
+    function clamp(val, min, max) {
+        return Math.min(Math.max(val, min), max)
+    }
 }