问题
When applying a LevelAdjust effect to an image, Qt doesn't seem to handle the edges properly.
I have a set of svg icons, all drawn in black. I would like to change their color easily on the fly. I am experimenting with the LevelAdjust effect from QtGraphicalEffects 1.12. According to the doc, using minimumOutput should shift the color curve in a linear fashion: blacks will correspond to minimumOutput, white will be white, and colors in between will be a prorated version of minimumOutput.
If I try the following:
Rectangle {
height: 100
width: 100
Image {
id: iconImage
source: "qrc:/images/circles.svg"
anchors.centerIn: parent
width: 0.8 * parent.width
height: width
sourceSize.width: width
sourceSize.height: width
fillMode: Image.PreserveAspectFit
}
LevelAdjust {
anchors.fill: iconImage
source: iconImage
minimumOutput: "#0098FE8F"
}
}
with my svg being as simple as possible:
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.0" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50" fill-rule="evenodd" style="paint-order:normal"/>
</svg>
then the inside of the circle takes the expected colour. However, the edges are simply wrong. When rendering the circle, it looks like Qt does some anti-aliasing. But these extra pixels are ignored. I end up with edges which look wrong, but are also darker than the new colour (magnified result here):
I would have expected their colour to be shifted as needed too. The result is the same on windows, and Android. Am I doing anything wrong?
Edit on 2019/09/05:
Based on the accepted answer and suggestion below, I created the following ColoredImage.qml component:
import QtQuick 2.0
import QtGraphicalEffects 1.12
Item {
id: imageWrapper
property bool colored: true
property string color: "#FFFF0000"
// Replicate some Image properties:
property string source
property var fillMode: Image.PreserveAspectFit
property var status: image.status
property real progress: image.progress
Image {
id: image
source: imageWrapper.source
anchors.fill: parent
sourceSize.width: width
sourceSize.height: height
fillMode: imageWrapper.fillMode
visible: !imageWrapper.colored
}
ColorOverlay {
id: overlay
anchors.fill: image
source: image
color: imageWrapper.color
visible: imageWrapper.colored
}
}
Thanks again!
回答1:
In your iconImage, you must set:
visible: false
You are seeing the original black icon under the LevelAdjust item through its semi-transparent anti-aliased edges.
来源:https://stackoverflow.com/questions/57788376/qt-qml-leveladjust-shows-strange-edge-effects-when-applied-to-svg-source