I am trying to add some blur effect on an image in my QtQucick app. Following is a simple snippet that can load an image, and put on it a custom polygon. What should I add to my code to make inside of the polygon looks blurry!
Thanks in advance.
import QtQuick 2.15
import QtQuick.Window 2.15
Window
{
id: main_window
width: 640
height: 480
visible: true
title: qsTr("Hello World")
property var mpoints: [Qt.point(20, 20), Qt.point(20, 300), Qt.point(300, 300), Qt.point(300, 20)]
Image
{
id: m_image
anchors.fill: parent
source: "file:///C:/Users/LeXela/Pictures/test.jpg"
cache: false
}
Canvas
{
anchors.fill: parent
onPaint:
{
var ctx = getContext("2d");
ctx.clearRect(0, 0, main_window.width, main_window.height);
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "white";
ctx.globalAlpha = 0.6;
ctx.beginPath();
ctx.moveTo(mpoints[0].x, mpoints[0].y)
for(let i = 1; i < mpoints.length; i++)
ctx.lineTo(mpoints[i].x, mpoints[i].y);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
}
}
You can render the Image twice with the second instance (1) sampled at a lower resolution by setting sourceSize
, (2) then, you can render a clipped version of the lower resolution image by defining a polygon using ShapePath
and using that with OpacityMask
:
import QtQuick
import QtQuick.Controls
import QtQuick.Shapes
import Qt5Compat.GraphicalEffects
Page {
property list<point> mpoints: [Qt.point(100, 150), Qt.point(300, 150), Qt.point(200, 250)]
Image
{
id: img
width: 400
height: 350
source: "butterfly.png"
}
Image {
id: blur
width: img.width
height: img.height
source: img.source
sourceSize: Qt.size(32, 32)
visible: false
}
Item {
id: mask
width: img.width
height: img.height
Shape {
id: polygon
ShapePath {
fillColor: "red"
strokeColor: "red"
startX: mpoints[0].x; startY: mpoints[0].y
PathLine { x: mpoints[1].x; y: mpoints[1].y }
PathLine { x: mpoints[2].x; y: mpoints[2].y }
}
}
visible: false
}
OpacityMask {
anchors.fill: mask
source: blur
maskSource: mask
}
}
// butterfly.png : https://raw.githubusercontent.com/stephenquan/stephenquan.github.io/master/images/qt/Original_butterfly.png
You can Try it Online!
Here's a version where the polygon vertices can move:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Shapes
import Qt5Compat.GraphicalEffects
Page {
property list<point> mpoints: [Qt.point(100, 150), Qt.point(200, 50), Qt.point(300, 150), Qt.point(200, 250)]
property int msize: 20
Image
{
id: img
width: 400
height: 350
source: "butterfly.png"
}
Item {
id: blur
anchors.fill: parent
Image {
width: img.width
height: img.height
source: img.source
sourceSize: Qt.size(img.width / blurSlider.value, img.height / blurSlider.value)
}
visible: false
}
Item {
id: polygon
anchors.fill: parent
visible: false
Repeater {
model: mpoints.length - 2
Shape {
property point firstPoint: mpoints[index]
property point secondPoint: mpoints[index+1]
property point lastPoint: mpoints[mpoints.length - 1]
ShapePath {
strokeColor: "orange"
fillColor: "orange"
startX: firstPoint.x; startY: firstPoint.y
PathLine { x: secondPoint.x; y: secondPoint.y }
PathLine { x: lastPoint.x; y: lastPoint.y }
}
}
}
}
Repeater {
model: mpoints.length
Shape {
property point thisPoint: mpoints[index]
property point nextPoint: mpoints[(index + 1) % mpoints.length]
ShapePath {
strokeColor: "blue"
strokeWidth: 2
startX: thisPoint.x; startY: thisPoint.y
PathLine { x: nextPoint.x; y: nextPoint.y }
}
}
}
OpacityMask {
anchors.fill: parent
source: blur
maskSource: polygon
invert: invertCheckBox.checked
}
Repeater {
model: mpoints
Rectangle {
x: modelData.x -msize / 2
y: modelData.y -msize / 2
width: msize
height: msize
color: "transparent"
border.color: "red"
border.width: 2
DragHandler {
onGrabChanged: {
switch (transition) {
case 1:
break;
case 2:
Qt.callLater(movePoint, index, parent.x + msize / 2, parent.y + msize / 2);
parent.x = -msize / 2;
parent.y = -msize / 2;
break;
}
}
}
}
}
footer: Frame {
RowLayout {
CheckBox { id: invertCheckBox; text: "Invert" }
Slider { id: blurSlider; from: 1; to: 10; value: 10 }
Label { text: "Blur %1".arg(blurSlider.value.toFixed(1)) }
}
}
function movePoint(index, newx, newy) {
mpoints[index] = Qt.point(newx, newy);
}
}
// butterfly.png : https://raw.githubusercontent.com/stephenquan/stephenquan.github.io/master/images/qt/Original_butterfly.png
You can Try it Online!