Image with radius in QML
-
wrote on 22 Jun 2011, 01:43 last edited by
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?
-
wrote on 22 Jun 2011, 02:04 last edited by
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.
-
wrote on 22 Jun 2011, 04:33 last edited by
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); } " }
}
@ -
wrote on 22 Jun 2011, 04:43 last edited by
Yes, fantastic :-)
-
wrote on 22 Jun 2011, 09:07 last edited by
Thank you for your answers!
-
wrote on 22 Jun 2011, 11:19 last edited by
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.
-
wrote on 22 Jun 2011, 12:53 last edited by
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.
-
wrote on 22 Jun 2011, 13:40 last edited by
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.
-
wrote on 22 Jun 2011, 14:09 last edited by
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?
-
wrote on 22 Jun 2011, 14:24 last edited by
I am afraid, that the solution I proposed indeed does not work. Sorry for setting you on the wrong track.
-
wrote on 1 Dec 2013, 16:54 last edited by
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.
-
wrote on 9 Apr 2014, 05:45 last edited by
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.
-
wrote on 9 Apr 2014, 08:09 last edited by
[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!