Rounded Image in Qt6
-
Qt switched to MultiEffect for all effects of image processing.
And I can't manage to make a working example for an image that has rounded corners.
The "mask" property is not working as expected, or I'm just doing something wrong.If anyone could post an example code of an Image with rounded corners I'd really appreciate it. (By using only Qt6)
For referrence I'm posting a working example of it in Qt5:
Image{ id: profileImage source: contactData.imageURL Layout.preferredHeight: parent.height Layout.preferredWidth: height asynchronous: true fillMode: Image.PreserveAspectCrop layer.enabled: true layer.effect: OpacityMask{ maskSource: Item{ width: profileImage.width height: profileImage.height Rectangle{ anchors.centerIn: parent width: Math.min(profileImage.width, profileImage.height) height: width radius: 50 } } } }
-
The easyest way in Qt6 would be using the Qt5Compat.GraphicalEffects.
This is how to use it:
import QtQuick import Qt5Compat.GraphicalEffects Item { anchors.fill: parent Image { id: img source: 'your image path' width: parent.width/2 height: width anchors.centerIn: parent fillMode: Image.PreserveAspectCrop layer.enabled: true layer.effect: OpacityMask { maskSource: mask } } Rectangle { id: mask width: parent.width/2 height: width radius: width/2 visible: false } }
-
@imahgin There's MultiEffect in Qt 6 : https://doc.qt.io/qt-6/qml-qtquick-effects-multieffect.html
-
As I said, the Qt5 example works. I would appreciate a Qt6 example using MultiEffect.
Tried it myself, but I just can't get it to work. This is my code:
Item { id: _avatarRoot Image { id: _avatar anchors.fill: parent visible: source !== "" asynchronous: true fillMode: Image.PreserveAspectCrop source: _root.sourceImage } MultiEffect { source: _avatar anchors.fill: _avatar maskEnabled: true maskSource: Rectangle { radius: 20 height: _avatarRoot.height width: _avatarRoot.width visible: false } maskSpreadAtMin: 0.4 maskThresholdMin: 0.6 } }
-
try this:
Image { id: sourceItem source: "" anchors.centerIn: parent width: 300 height: 300 visible: false } MultiEffect { source: sourceItem anchors.fill: sourceItem maskEnabled: true maskSource: mask } Item { id: mask width: sourceItem.width height: sourceItem.height layer.enabled: true visible: false Rectangle { width: sourceItem.width height: sourceItem.height radius: width/2 color: "black" } }
maskSource : Item
Source item for the mask effect. Should point to ShaderEffectSource, item with layer.enabled set to true, or to an item that can be directly used as a texture source (e.g. Image). The alpha channel of the source item is used for masking.
-
@keith-pham it works! Thank you so much. Marking it as solved.
-
M Marko Stanke has marked this topic as solved on
-
M mzimmers referenced this topic on
-
S SGaist referenced this topic on
-
This has sorta worked for me, but there is what I would consider to be a major problem. There doesn't seem to be any antialiasing, meaning that curved edges are jagged and don't look that good. Setting layer.smooth to true on the mask item does help a little bit, but it's still not as good as OpacityMask which didn't have any antialiasing problems
I've been trying a lot but I can't seem to get it to work properly. It's seemingly related to this where the layer property causes issues, but I haven't gotten the solutions from there to work here no matter which layer properties I set in which elements
-
To anyone seeing this in the future who has the same problem as me with the jagged edges: The problem seems to actually be caused by the smoothstep that the Qt6 MultiEffect uses but the Qt5 OpacityMask doesn't. This is used for the maskThreshold- and maskSpreadAt- properties of MultiEffect. I don't really understand how these properties work, but by recreating this part of the shader in my own project I found out that if the first two elements of
mask
are about 0 and 1 respectively, the edges will be smooth. By looking into how these values are calculated, I found that setting maskThresholdMin to 0.5 and maskSpreadAtMin to 1.0 reaches basically this and the edges will then be smooth enoughTLDR: Set these values in the MultiEffect:
maskThresholdMin: 0.5
maskSpreadAtMin: 1.0
Edit: And just to clarify,
layer.smooth: true
also has to be set on the mask item