Image with radius in QML
-
Hi, how could I set rounded corners in an Image in QML? I tried simulated it with a rectangle behind but it didn't work. Any suggests?
-
There is no direct way to set rounded corner for Image. But as you think, we need some tricks. Rectangle behide the Image is not work, but you can try in front of the Image, set the Rectangle's color to "transparent", and set it's border and radius.
-
It is possible with the "QML Shaders":http://labs.qt.nokia.com/2011/05/03/qml-shadereffectitem-on-qgraphicsview/ plugin.
@
import QtQuick 1.0
import Qt.labs.shaders 1.0Item {
width: 600
height: 300Rectangle { id: mask anchors.centerIn: parent width: 400 height: 200 radius: 20 } Image { id: image anchors.fill: mask source: "test.jpg" } ShaderEffectSource { id: sourceMask smooth: true hideSource: true sourceItem: mask } ShaderEffectSource { id: sourceImage hideSource: true sourceItem: image } ShaderEffectItem { id: maskEffect anchors.fill: mask property variant sourceTexture: sourceImage property variant maskTexture: sourceMask vertexShader: " uniform highp mat4 qt_ModelViewProjectionMatrix; attribute highp vec4 qt_Vertex; attribute highp vec2 qt_MultiTexCoord0; varying highp vec2 qt_TexCoord; void main(void) { qt_TexCoord = qt_MultiTexCoord0; gl_Position = qt_ModelViewProjectionMatrix * qt_Vertex; } " fragmentShader: " uniform lowp sampler2D sourceTexture; uniform lowp sampler2D maskTexture; varying highp vec2 qt_TexCoord; void main (void) { vec4 c = texture2D(sourceTexture, qt_TexCoord); vec4 m = texture2D(maskTexture, qt_TexCoord); gl_FragColor = vec4(c.rgb, m.a); } " }
}
@ -
Yes, fantastic :-)
-
Thank you for your answers!
-
Interesting approach, but to be honest, I don't think this kind of code is really what we should strive for in QML. It is not really readable, and also not really declarative.
I'm sure your code produces a faster UI, but for simplicity, I would go for something like this:
@
import QtQuick 1.0
Item {
width: 600
height: 300Rectangle { id: mask anchors.centerIn: parent width: 400 height: 200 radius: 20 Image { id: image anchors.fill: parent source: "test.jpg" } }
}
@That should work as well, and is, IMHO, clearer to read.
-
At the beginning I tried with that code but it didn't work. The image is set over the rectangle hidding the round corners. I will try again but I think it doesn't work.
If I nest, in the opposite way, the Rectangle inside the Image, it shows the border over the image but it doesn't hide the corners either.
-
Sorry, you probably need to enable clipping.
@
import QtQuick 1.0
Item {
width: 600
height: 300Rectangle { id: mask anchors.centerIn: parent width: 400 height: 200 radius: 20 clip: true Image { id: image anchors.fill: parent source: "test.jpg" } }
}
@Edit:
On the other hand: the docs to state:
[quote]Non-rectangular clipping regions are not supported for performance reasons.[/quote]So, perhaps a rounded rect will not clip properly after all.
-
I tried the code but it doesn't work. I copied it directly to qt and tried it.
The same is happening, the image is over the rectangle. How to make it fit to the shape of the rectangle?
-
I am afraid, that the solution I proposed indeed does not work. Sorry for setting you on the wrong track.
-
Hello,
I am trying the shader solution, but it gives me this error at runtime:
@
QGLShaderProgram::addShader: Program and shader are not associated with same context.
QGLShaderProgram::addShader: Program and shader are not associated with same context.
QGLShader::link: "Link Error: Vertex shader is missing.
Link Error: Fragment shader is missing.
"
ShaderEffectItem: Shader compilation failed:
"Link Error: Vertex shader is missing.
Link Error: Fragment shader is missing.
"
QGLShader::link: "Link Error: Vertex shader is missing.
Link Error: Fragment shader is missing.
"
QGLShaderProgram::uniformLocation( qt_ModelViewProjectionMatrix ): shader program is not linked
QGLShaderProgram::addShader: Program and shader are not associated with same context.
QGLShaderProgram::addShader: Program and shader are not associated with same context.
QGLShader::link: "Link Error: Vertex shader is missing.
@And this is the code I have used:
@
Item {
width: 200
height: 200
//radius: 20
//border.width: 6
//border.color: "#ffea00"signal tapOnProfilePicture property alias profileImageSource: image.source Rectangle { id: mask anchors.centerIn: parent width: 200 height: 200 radius: 20 } Image { id: image anchors.fill: mask source: "qrc:/images/profile-mask.png" } ShaderEffectSource { id: sourceMask smooth: true hideSource: true sourceItem: mask } ShaderEffectSource { id: sourceImage hideSource: true sourceItem: image } ShaderEffectItem { id: maskEffect anchors.fill: mask property variant sourceTexture: sourceImage property variant maskTexture: sourceMask vertexShader: " uniform highp mat4 qt_ModelViewProjectionMatrix; attribute highp vec4 qt_Vertex; attribute highp vec2 qt_MultiTexCoord0; varying highp vec2 qt_TexCoord; void main(void) { qt_TexCoord = qt_MultiTexCoord0; gl_Position = qt_ModelViewProjectionMatrix * qt_Vertex; } " fragmentShader: " uniform lowp sampler2D sourceTexture; uniform lowp sampler2D maskTexture; varying highp vec2 qt_TexCoord; void main (void) { highp vec4 c = texture2D(sourceTexture, qt_TexCoord); highp vec4 m = texture2D(maskTexture, qt_TexCoord); gl_FragColor = vec4(c.rgb, m.a); } " } MouseArea { z: 10 anchors.fill: parent onClicked: { tapOnProfilePicture() } }
}
@Notice I have added highp to vec4 declarations to avoid other errors.
-
Hi you can use an "OpacityMask":http://qt-project.org/doc/qt-5/qml-qtgraphicaleffects-opacitymask.html. Use a rounded image and mask your image with it.
-
[quote author="Brexis" date="1397022356"]Hi you can use an "OpacityMask":http://qt-project.org/doc/qt-5/qml-qtgraphicaleffects-opacitymask.html. Use a rounded image and mask your image with it.[/quote]
Yes, that is a good solution!