Search code examples
imageqmlopacitymask

Qml OpacityMask reduces image quality


I have a Rectangle that contains an Image. I'm trying to create a rounded image with a black border. I've tried using an OpacityMask, but when I do, it reduces the image quality. Also there is a very small amount of white space in some places between the border and the image. I've provided the code below. The commented out lines are things I've tried to no avail. I've also tried making the Rectangle and Image siblings contained within an Item with a separate sibling OpacityMask but get the same result.

Does anyone know a better way of doing this. Also does anyone know a better way of creating the border - at the moment I'm stopping the image covering the border by using

anchors.margins: imageRect.border.width

enter image description here enter image description here

Rectangle {
     id: imageRect
     property int spacer: 10 
     property int spacedWidth: imageDel.width - spacer
     anchors.horizontalCenter: parent.horizontalCenter
     width: spacedWidth
     height: spacedWidth / imageListModel.getImageWToHRatio()  
     border.color: "black"
     border.width: 2
     radius: imageRadius
     //clip: true

     Image {
        id: image
        source: "image://lmImageProvider/" + rowIndex + "_" + index
        //sourceSize: Qt.size(parent.width, parent.height)
        anchors.fill: parent
        anchors.margins: imageRect.border.width
        cache: false
        //visible: false
        //fillMode: Image.PreserveAspectCrop
        layer.enabled: true
        layer.smooth: true
        //layer.textureSize: "600x900"
        layer.effect: OpacityMask {
           maskSource: imageRect
           // cached: true
        }
        //mipmap: true


        property bool reload: reloadImageRole
        onReloadChanged: {
           source = ""
           source = "image://lmImageProvider/" + rowIndex + "_" + index
        }

        MouseArea {
           anchors.fill: parent
           onClicked: {
              imageListModel.toggleSelected(rowIndex + "_" + index)
           }
        }
     }
  }

Solution

  • Still not sure why the above code doesn't work. Also not sure why my original attempt at "making the Rectangle and Image siblings contained within an Item with a separate sibling OpacityMask" (which was based on another answer in Stack Overflow), didn't work. But upon much further investigation, I found another answer which was a slight variation on the "making the Rectangle and Image siblings contained within an Item with a separate sibling OpacityMask" which did work. Updated code is below:

    Rectangle {
       id: imageRect
       property int spacer: 10 
       property int spacedWidth: imageDel.width - spacer
       anchors.horizontalCenter: parent.horizontalCenter
       width: spacedWidth
       height: spacedWidth / imageListModel.getImageWToHRatio()  
       border.color: "black"
       border.width: indImageBorderWidth
       radius: indImageRadius
    
       Image {
          id: image
          source: "image://lmImageProvider/" + rowIndex + "_" + index
          anchors.fill: parent
          anchors.margins: imageRect.border.width - 2
          cache: false
          visible: false
    
          property bool reload: reloadImageRole
          onReloadChanged: {
             source = ""
             source = "image://lmImageProvider/" + rowIndex + "_" + index
          }
       }
    
       Rectangle{
          id: maskRect
          anchors.fill: image
          radius: indImageRadius - 3
          visible: false
          z: image.z + 1
       }
    
       OpacityMask {
          anchors.fill: image
          source: image
          maskSource: maskRect
       }
       MouseArea {
          anchors.fill: parent
          onClicked: {
          //imageListModel.toggleSelected(rowIndex + "_" + index)
          console.log("Image Clicked: " + rowIndex + "_" + index)
       }
    }
    

    }