versiones guia espaƱol descargar actualizar qml qt5 qtquick2

qml - guia - qgis manual



Imagen esquinas redondeadas en QML. (7)

Para mi sorpresa, el componente Image no tiene propiedad de radius . Intenté emular las esquinas redondeadas colocando la imagen en un Rectangle redondeado, pero no corta las esquinas.

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" } }

¿Cómo puedo crear una imagen con esquinas redondeadas correctamente?



Cuando su fondo es un color sólido o cuando nunca está moviendo la imagen, una forma rápida de hacer esquinas redondeadas es superponer su Image con otra (o con una BorderImage ) que solo dibuja las esquinas.

Cuando esto no es una opción, pero está utilizando OpenGL, otra forma es aplicar una máscara a la imagen a través de un sombreador de píxeles. Consulte http://blog.qt.digia.com/blog/2011/05/03/qml-shadereffectitem-on-qgraphicsview/ para ver un complemento que funciona sobre Qt 4.

Finalmente, también es posible escribir un QDeclarativeImageProvider que preprocesa tu imagen para redondear las esquinas.


Este código te ayudaría

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" } }


Sé que llego un poco tarde a la fiesta, pero llegué aquí buscando en Google, así que pensé que ayudaría a las generaciones futuras :) QtGraphicalEffects OpacityMask debería hacer esto un poco más simple (tuve problemas con el enfoque de efecto de capa)

Image { id: imgAuthor width: 64 height: 64 source: "qrc:/res/sample_avatar.jpg" visible: false // this is needed or the corners of the image will be visible underneath the opacity mask } OpacityMask { anchors.fill: imgAuthor source: imgAuthor maskSource: Rectangle { width: imgAuthor.width height: imgAuthor.height radius: 8 visible: false // this also needs to be invisible or it will cover up the image } }


Si bien tanto la respuesta aceptada como la respuesta de @fury funcionaron igual de bien para mí (Qt 5.9.3), ambas dejaron algunas aberraciones en las esquinas cuando se aplicaron a imágenes rasterizadas (no tenían las que tenían SVG). Lo que me funcionó mejor en todos los casos fue aplicar la OpacityMask a un elemento circundante, por ejemplo, como el rectángulo en la publicación original.

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" } }


Si tiene un fondo unicolor, puede dibujar con el borde de un rectángulo redondeado en la parte superior.

Image{ id:img } Rectangle { // rounded corners for img anchors.fill: img color: "transparent" border.color: "blue" // color of background border.width: 4 radius: 4 }


Una solución oficial incorporada existe a partir de Qt 5 gracias al módulo QtGraphicalEffects y me sorprende bastante descubrir que nadie proporcionó una solución tan simple.

Entre los otros efectos, OpacityMask es el tipo que se va a explotar para este propósito. La idea es enmascarar la Image origen con un Rectangle que tenga un radius configurado correctamente. Aquí va el ejemplo más simple usando layering :

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) } } } }

Este código mínimo produce un buen resultado para las imágenes cuadradas, pero también tiene en cuenta las imágenes no cuadradas a través de la variable de adapt . Al establecer la bandera en false la máscara producida siempre será un círculo, independientemente del tamaño de la imagen. Esto es posible debido al uso de un Item externo que llena la fuente y permite que la máscara real (el Rectangle interior) tenga el tamaño deseado. Obviamente, puede deshacerse del Item externo, si simplemente apunta a una máscara que llena la fuente, independientemente de su relación de aspecto .

Aquí hay una linda imagen de gato con un formato cuadrado ( izquierda ), un formato no cuadrado con adapt: true ( centro ) y, finalmente, un formato no cuadrado y adapt: false ( derecha ):

Los detalles de implementación de esta solución son muy similares a los de la respuesta basada en sombreado en la otra respuesta agradable (cfr. El código fuente QML para OpacityMask que se puede encontrar here - SourceProxy simplemente devuelve una fuente OpacityMask bien formada para alimentar el efecto) .

Si no desea depender del módulo QtGraphicalEffects (bueno, de la presencia de OpacityMask.qml realidad), puede OpacityMask.qml el efecto con shaders. Aparte de la solución ya provista, otro enfoque es utilizar las funciones step , smoothstep y fwidth . Aquí está el código:

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; }" } }

De manera similar al primer enfoque, se agregan propiedades rounded y de adapt para controlar la apariencia visual del efecto como se explicó anteriormente.