令我惊讶的是,Image
组件没有radius
属性。我尝试通过将图像放在圆角Rectangle
中来模拟圆角,但它不会剪切角落。
Rectangle {
anchors.right: rectContentBg.left
anchors.top: rectContentBg.top
anchors.margins: 8
radius: 8
width: 64
height: 64
Image {
id: imgAuthor
opacity: 1
smooth: false
anchors.fill: parent
source: "qrc:/res/sample_avatar.jpg"
}
}
如何正确创建圆角图像?
答案 0 :(得分:40)
由于QtGraphicalEffects
模块,Qt 5中存在内置的官方解决方案,我很惊讶地发现没有人提供这样简单的解决方案。
在其他效果中,OpacityMask
是为此目的而被利用的类型。我们的想法是使用具有正确设置Image
的{{1}}来屏蔽来源Rectangle
。以下是使用layering:
radius
这个最小代码为方形图像产生了很好的效果,但是
它还通过Image {
id: img
property bool rounded: true
property bool adapt: true
layer.enabled: rounded
layer.effect: OpacityMask {
maskSource: Item {
width: img.width
height: img.height
Rectangle {
anchors.centerIn: parent
width: img.adapt ? img.width : Math.min(img.width, img.height)
height: img.adapt ? img.height : width
radius: Math.min(width, height)
}
}
}
}
变量考虑非方形图像。通过将标志设置为adapt
,无论图像大小如何,生成的蒙版始终为圆形。这是可能的,因为使用外部false
填充源并允许真正的掩码(内部Item
)在适当的大小。 你可以明显地摆脱外部Rectangle
,如果你只是针对一个填充源的面具,无论其纵横比。
这是一个可爱的猫图像,方形格式(左),非方格式Item
(中心),最后是非方格式和adapt: true
(右):
此解决方案的实现细节与其他nice answer中基于着色器的答案的实现细节非常相似(cfr。adapt: false
的{{1}}的QML源代码here - OpacityMask
只返回格式正确的SourceProxy
来提供效果。)
如果您不想依赖ShaderEffectSource
模块(嗯,实际存在QtGraphicalEffects
),您可以使用着色器重新实现效果。除了已经提供的解决方案,另一种方法是使用step
,smoothstep
和fwidth
函数。这是代码:
OpacityMask.qml
与第一种方法类似,添加了import QtQuick 2.5
Image {
id: image
property bool rounded: true
property bool adapt: true
layer.enabled: rounded
layer.effect: ShaderEffect {
property real adjustX: image.adapt ? Math.max(width / height, 1) : 1
property real adjustY: image.adapt ? Math.max(1 / (width / height), 1) : 1
fragmentShader: "
#ifdef GL_ES
precision lowp float;
#endif // GL_ES
varying highp vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform lowp float adjustX;
uniform lowp float adjustY;
void main(void) {
lowp float x, y;
x = (qt_TexCoord0.x - 0.5) * adjustX;
y = (qt_TexCoord0.y - 0.5) * adjustY;
float delta = adjustX != 1.0 ? fwidth(y) / 2.0 : fwidth(x) / 2.0;
gl_FragColor = texture2D(source, qt_TexCoord0).rgba
* step(x * x + y * y, 0.25)
* smoothstep((x * x + y * y) , 0.25 + delta, 0.25)
* qt_Opacity;
}"
}
}
和rounded
属性来控制效果的视觉外观,如上所述。
答案 1 :(得分:7)
当您的背景为纯色或者您从未移动图片时,快速制作圆角的方法是将您的Image
与另一个(或BorderImage
)重叠只画出角落。
如果这不是一个选项,但您使用的是OpenGL,那么另一种方法是通过像素着色器将遮罩应用于图像。有关在Qt 4之上工作的插件,请参阅http://blog.qt.digia.com/blog/2011/05/03/qml-shadereffectitem-on-qgraphicsview/。
最后,还可以编写一个预处理图像的QDeclarativeImageProvider
来使角落四舍五入。
答案 2 :(得分:6)
This code would help you
Rectangle {
width: 200
height: 200
color: "transparent"
//this Rectangle is needed to keep the source image's fillMode
Rectangle {
id: imageSource
anchors.fill: parent
Image {
anchors.fill: parent
source: "your_image_file_path"
fillMode: Image.PreserveAspectCrop
}
visible: false
layer.enabled: true
}
Rectangle {
id: maskLayer
anchors.fill: parent
radius: parent.width / 2
color: "red"
border.color: "black"
layer.enabled: true
layer.samplerName: "maskSource"
layer.effect: ShaderEffect {
property var colorSource: imageSource
fragmentShader: "
uniform lowp sampler2D colorSource;
uniform lowp sampler2D maskSource;
uniform lowp float qt_Opacity;
varying highp vec2 qt_TexCoord0;
void main() {
gl_FragColor =
texture2D(colorSource, qt_TexCoord0)
* texture2D(maskSource, qt_TexCoord0).a
* qt_Opacity;
}
"
}
}
// only draw border line
Rectangle {
anchors.fill: parent
radius: parent.width / 2
border.color: "black"
border.width: 2
color: "transparent"
}
}
答案 3 :(得分:5)
QML目前仅支持矩形剪切,但您可能需要查看qt-components项目中的DeclarativeMaskedImage:
答案 4 :(得分:5)
如果您有单色背景,则可以使用顶部圆角矩形的边框进行绘制。
Image{
id:img
}
Rectangle { // rounded corners for img
anchors.fill: img
color: "transparent"
border.color: "blue" // color of background
border.width: 4
radius: 4
}
答案 5 :(得分:4)
我知道我参加派对有点晚了,但是我通过谷歌搜索来到这里,所以我想我会帮助后代:) QtGraphicalEffects OpacityMask应该更简单地做到这一点(我有层效应方法的问题) )
Repo.insert_all! MyApp.UserRole, [%{user_id: 1, role_id: 1},
%{user_id: 2, role_id: 1},
%{user_id: 2, role_id: 2}]
答案 6 :(得分:2)
虽然接受的答案和the one from @fury同样适用于我(Qt 5.9.3),但是当应用于光栅图像时,它们都会在角落中留下一些像差(没有那些带有SVG的像素)。在所有情况下最适合我的是将OpacityMask
应用于周围的项目,例如就像原帖中的矩形一样。
Rectangle {
id: root;
anchors.right: rectContentBg.left
anchors.top: rectContentBg.top
anchors.margins: 8
radius: 8
width: 64
height: 64
// apply rounded corners mask
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Rectangle {
x: root.x; y: root.y
width: root.width
height: root.height
radius: root.radius
}
}
Image {
id: imgAuthor
opacity: 1
smooth: false
anchors.fill: parent
source: "qrc:/res/sample_avatar.jpg"
}
}