QML 中的图像圆角
令我惊讶的是,Image
组件没有 radius
属性。我尝试通过将图像放入圆角矩形中来模拟圆角,但它不会剪切角。
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"
}
}
如何正确创建带有圆角的图像?
To my surprise, the Image
component has no radius
property. I tried emulating the rounded corners by putting the image in a rounded Rectangle
, but it does not clip the corners.
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"
}
}
How can I create an image with rounded corners properly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
由于 QtGraphicalEffects 模块,从 Qt 5 开始就存在内置的官方解决方案,我很惊讶地发现没有人提供如此简单的解决方案。如果您的目标是 Qt 6.x,不幸的是,
QtGraphicalEffects
已被弃用,因此请跳转到答案的第二部分,该部分提出了独立于QtGraphicalEffects
的解决方案。QtGraphicalEffects
解决方案在其他效果中,
OpacityMask
是用于此目的的类型。这个想法是用一个具有正确设置的半径
的矩形
来掩盖源Image
。 是使用 分层 的最简单示例:这 最少的代码可以为方形图像产生很好的结果,但是
它还通过
adapt
变量考虑非方形图像。通过将标志设置为false
,无论图像大小如何,生成的蒙版将始终是圆形。这是可能的,因为使用了外部Item
,它填充源并允许随意调整真实掩码(内部矩形
)的大小。 如果您只是瞄准填充源的遮罩,而不管其纵横比如何,您显然可以摆脱外部Item
。。这是一张可爱的猫图像,其格式为方形(左),带有
adapt: true
的非方形格式(中心),最后是非方形格式和adapt: false
(right):此解决方案的实现细节与基于着色器的答案非常相似在另一个好的答案中(参见
OpacityMask
的QML源代码,可以找到< a href="http://ftp.fau.de/qtproject/ministro/android/qt5/objects/5.1014-x86/qml/QtGraphicalEffects/OpacityMask.qml" rel="noreferrer">此处 -SourceProxy
只是返回一个格式良好的ShaderEffectSource
来提供效果)。无依赖解决方案
如果您不想 - 或不能 - 依赖于
QtGraphicalEffects
模块(好吧,依赖于OpacityMask.qml< /code> 实际上),您可以使用着色器重新实现效果。除了已经提供的解决方案之外,另一种方法是使用
step
,
smoothstep
和fwidth
函数。这是代码:与第一种方法类似,添加了
rounded
和adapt
属性来控制效果的视觉外观,如上所述。A built-in official solution exists as of Qt 5 thanks to the
QtGraphicalEffects
module and I'm quite surprised to find out that no one provided such a simple solution. If you are targeting Qt 6.xQtGraphicalEffects
is unfortunately deprecated so jump to the second part of the answer which proposes a solution independent ofQtGraphicalEffects
.QtGraphicalEffects
solutionAmong the other effects
OpacityMask
is the type to be exploited for this purpose. The idea is to mask the sourceImage
with aRectangle
that has a correctly setradius
. Here goes the simplest example using layering:This minimum code produces a nice result for square images but
it also takes in account non-square images via the
adapt
variable. By setting the flag tofalse
the produced mask will always be a circle, regardless of the image size. That is possible due to the usage of an externalItem
which fills the source and allows the real mask (the innerRectangle
) to be sized at please. You can obviously get rid of the externalItem
, if you simply aim to a mask that fills the source, regardless of the its aspect ratio.Here is a cute cat image with a square format (left), a non-square format with
adapt: true
(center) and finally a non-square format andadapt: false
(right):The implementation details of this solution are very similar to those of the shader-based answer in the other nice answer (cfr. the QML source code for
OpacityMask
that can be found here -SourceProxy
simply returns a well-formedShaderEffectSource
to feed the effect).No-dep solution
If you don't want to - or can't - depend on the
QtGraphicalEffects
module (well, on the presence ofOpacityMask.qml
actually), you can reimplement the effect with shaders. Apart from the already provided solution another approach is to usestep
,smoothstep
andfwidth
functions. Here is the code:Similarly to the first approach,
rounded
andadapt
properties are added to control the visual appearance of the effect as discussed above.这段代码可以帮助你
This code would help you
当您的背景是纯色或从不移动图像时,制作圆角的一种快速方法是将您的
Image
与另一个图像(或与BorderImage
) 只绘制角点。如果这不是一个选项,但您正在使用 OpenGL,则另一种方法是通过像素着色器将遮罩应用于图像。请参阅http://blog.qt.digia .com/blog/2011/05/03/qml-shadereffectitem-on-qgraphicsview/ 用于在 Qt 4 之上工作的插件。
最后,还可以编写
QDeclarativeImageProvider
对图像进行预处理以使角变圆。When your background is a solid color or when you're never moving the image, a fast way to make rounded corners is to overlap your
Image
with another one (or with aBorderImage
) that only draws the corners.When this is not an option, but you are using OpenGL, then another way is to apply a mask to the image through a pixel shader. See http://blog.qt.digia.com/blog/2011/05/03/qml-shadereffectitem-on-qgraphicsview/ for a plugin that works on top of Qt 4.
Finally, it's also possible to write a
QDeclarativeImageProvider
that preprocesses your image to make the corners rounded.虽然接受的答案和 来自 @fury 的答案对我来说同样有效(Qt 5.9.3),但他们都离开了当应用于光栅图像时,角落会出现一些像差(SVG 中没有)。在所有情况下对我来说最有效的是将
OpacityMask
应用于周围的项目,例如原始帖子中的矩形。While both the accepted answer and the one from @fury worked equally well for me (Qt 5.9.3), they both left some aberrations in the corners when applied to raster images (didn't have those with SVG). What worked best for me in all cases was to apply the
OpacityMask
to a surrounding item, e.g. like the rectangle in the original post.如果您有单色背景,则可以在顶部绘制圆角矩形的边框。
If you have a unicolor background, you can draw with the border of a rounded rectangle on top.
QML 目前仅支持矩形裁剪,但您可能想看看 qt-components 项目中的 DeclarativeMaskedImage:
http://qt.gitorious.org/qt-components/qt-components/blobs/master/src/symbian/sdeclarativemaskedimage.h
QML currently supports only rectangular clipping, but you might want to take a look at DeclarativeMaskedImage in qt-components project:
http://qt.gitorious.org/qt-components/qt-components/blobs/master/src/symbian/sdeclarativemaskedimage.h
我知道我来晚了一点,但我通过谷歌搜索来到这里,所以我想我会帮助后代:) QtGraphicalEffects OpacityMask 应该更简单地做到这一点(我对图层效果方法有疑问)
I know I'm a little late to the party, but I got here by googling, so thought I'd help future generations :) QtGraphicalEffects OpacityMask should do this a bit more simply (I had issues with the layer effect approach)
如果您有单色背景,则可以在顶部绘制圆角矩形的边框。
If you have a unicolor background, you can draw with the border of a rounded rectangle on top.