Clip QML MediaPlayer to a round cornered rectangle container?
-
Hi! So I am using
MediaPlayer
to stream camera outputs in QML, and I want the display to fit into a round cornered rectangle. However, this seems surprisingly tricky.Here is how I want the corner to look like...
Here is how the corner actually look like, when I was rendering the images:
Here is my current code:
Item { property string cameraText: "" Rectangle { id: videoContainer height: 900 width: 1800 radius: 25 clip: true anchors.left: parent.left anchors.leftMargin: 25 anchors.top: parent.top anchors.topMargin: 25 Text { text: cameraText anchors.centerIn: parent font.pixelSize: 30 } MediaPlayer { id: mediaPlayer source: Qt.resolvedUrl("test.mp4") videoOutput: videoOutput } VideoOutput { id: videoOutput anchors.fill: parent fillMode: VideoOutput.PreserveAspectCrop } Component.onCompleted: { mediaPlayer.play(); } } }
You can see the
clip
property doesn't work, because the top left corner of the camera is still sharp, not round.Would appreciate any suggestions! I feel this should be a common use case, but I am very new to QML. Thanks!
-
Hi! So I am using
MediaPlayer
to stream camera outputs in QML, and I want the display to fit into a round cornered rectangle. However, this seems surprisingly tricky.Here is how I want the corner to look like...
Here is how the corner actually look like, when I was rendering the images:
Here is my current code:
Item { property string cameraText: "" Rectangle { id: videoContainer height: 900 width: 1800 radius: 25 clip: true anchors.left: parent.left anchors.leftMargin: 25 anchors.top: parent.top anchors.topMargin: 25 Text { text: cameraText anchors.centerIn: parent font.pixelSize: 30 } MediaPlayer { id: mediaPlayer source: Qt.resolvedUrl("test.mp4") videoOutput: videoOutput } VideoOutput { id: videoOutput anchors.fill: parent fillMode: VideoOutput.PreserveAspectCrop } Component.onCompleted: { mediaPlayer.play(); } } }
You can see the
clip
property doesn't work, because the top left corner of the camera is still sharp, not round.Would appreciate any suggestions! I feel this should be a common use case, but I am very new to QML. Thanks!
@charlie2024 - hi, I replied to a similar question sometime back; https://forum.qt.io/topic/131723/round-the-corner-of-map/6 - you need to use OpacityMask with layer.enabled/layer.effect. See the last part of the code in my reply.
Here's another example of OpacityMask with layer; https://stackoverflow.com/questions/6090740/image-rounded-corners-in-qml
-
Hi! So I am using
MediaPlayer
to stream camera outputs in QML, and I want the display to fit into a round cornered rectangle. However, this seems surprisingly tricky.Here is how I want the corner to look like...
Here is how the corner actually look like, when I was rendering the images:
Here is my current code:
Item { property string cameraText: "" Rectangle { id: videoContainer height: 900 width: 1800 radius: 25 clip: true anchors.left: parent.left anchors.leftMargin: 25 anchors.top: parent.top anchors.topMargin: 25 Text { text: cameraText anchors.centerIn: parent font.pixelSize: 30 } MediaPlayer { id: mediaPlayer source: Qt.resolvedUrl("test.mp4") videoOutput: videoOutput } VideoOutput { id: videoOutput anchors.fill: parent fillMode: VideoOutput.PreserveAspectCrop } Component.onCompleted: { mediaPlayer.play(); } } }
You can see the
clip
property doesn't work, because the top left corner of the camera is still sharp, not round.Would appreciate any suggestions! I feel this should be a common use case, but I am very new to QML. Thanks!
No need for
OpacityMask
or even clipping here.Just put a Rectangle with only a border on top of it.
In your example add
border.width: radius / 2
andcolor: "transparent"
to your Rectangle, andz: -1
to your MediaPlayer.It could be done a bit cleaner with a
Frame
or even aGroupBox
as the root item:GroupBox { anchors.centerIn: parent width: 400 height: 320 title: "Camera Name" padding: 12 topPadding: padding label.x: 20 label.y: 16 label.z: 2 background: Rectangle { color: "transparent" radius: parent.padding * 2 border.width: parent.padding border.color: "lightgrey" z: 1 } contentItem: Rectangle { color: "green" } // contentItem: VideoOutput { // id: videoOutput // fillMode: VideoOutput.PreserveAspectCrop // } // MediaPlayer { // id: mediaPlayer // source: Qt.resolvedUrl("test.mp4") // videoOutput: videoOutput // autoPlay: true // } }
Remove the green rectangle and uncomment the VideoOutput in your case.
Note that in order to put the background above the content I added
z: 1
to it.
I also add to fiddle with the topPadding and the x,y,z of the label to display the title as I guessed how you would want it.
It looks like this:
-
-
Thank you! I think
OpacityMask
doesn't exist in Qt6 anymore so I ended up with the second approach, which also seems simpler. But thanks anyway! Somehow I couldn't find that post you linked on SO before. Maybe it's the search keywords. -
No need for
OpacityMask
or even clipping here.Just put a Rectangle with only a border on top of it.
In your example add
border.width: radius / 2
andcolor: "transparent"
to your Rectangle, andz: -1
to your MediaPlayer.It could be done a bit cleaner with a
Frame
or even aGroupBox
as the root item:GroupBox { anchors.centerIn: parent width: 400 height: 320 title: "Camera Name" padding: 12 topPadding: padding label.x: 20 label.y: 16 label.z: 2 background: Rectangle { color: "transparent" radius: parent.padding * 2 border.width: parent.padding border.color: "lightgrey" z: 1 } contentItem: Rectangle { color: "green" } // contentItem: VideoOutput { // id: videoOutput // fillMode: VideoOutput.PreserveAspectCrop // } // MediaPlayer { // id: mediaPlayer // source: Qt.resolvedUrl("test.mp4") // videoOutput: videoOutput // autoPlay: true // } }
Remove the green rectangle and uncomment the VideoOutput in your case.
Note that in order to put the background above the content I added
z: 1
to it.
I also add to fiddle with the topPadding and the x,y,z of the label to display the title as I guessed how you would want it.
It looks like this:
@GrecKo Thank you! Just tried, worked like a charm! Will need to adjust the parameters to suit our case but yes the camera is rounded.
-
@GrecKo Thank you! Just tried, worked like a charm! Will need to adjust the parameters to suit our case but yes the camera is rounded.
@charlie2024 If you are moving forward with the existing method, no problem. However, for your information, Opacity Mask on Qt6 is now possible from Qt 6.2 onwards using the "Qt5Compat.GraphicalEffect" library. This library contains many graphical effects initially discontinued and later added due to high demand from developers like DropShadow, Gaussian Blur, etc.
Here is the link below
Qt5Compat GraphicalEffectHappy coding and happy learning :)