Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Qt6 color SVG using MultiEffect
QtWS: Super Early Bird Tickets Available!

Qt6 color SVG using MultiEffect

Scheduled Pinned Locked Moved Solved QML and Qt Quick
11 Posts 7 Posters 2.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    replied to christofer on last edited by
    #2

    @christofer I've experienced this as well. I think the problem is in how the .svg file is composed, specifically (but not only) the use of the "fill=" field. I snagged a circle.svg file with this content:

    <svg fill="#0000ff" height="200px" width="200px" version="1.1" id="Layer_1" viewBox="0 0 222.334 222.334" xml:space="preserve">
    <g>
    	<g>
    		<g>
    			<path d="M111.167,0C49.87,0,0,49.87,0,111.167s49.87,111.167,111.167,111.167s111.167-49.87,111.167-111.167S172.464,0,111.167,0
    				z M111.167,214.1c-56.758,0-102.933-46.175-102.933-102.933S54.409,8.235,111.167,8.235S214.1,54.409,214.1,111.167
    				S167.925,214.1,111.167,214.1z"/>
    		</g>
    	</g>
    </g>
    </svg>
    

    which produces this:
    blue.PNG
    Replacing the fill value from "#0000ff" to "none" produces a black circle.

    I tried a similar experiment with the puppy file and couldn't even get that to change color at all.

    So...I think the svg file has to be composed in a particular way in order to support fills, but I can't speak with any authority on this. Hopefully someone else with some .svg file knowledge can chime in.

    mzimmersM 1 Reply Last reply
    0
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    replied to mzimmers on last edited by
    #3

    Update: I tried a much simpler circle file:

    <svg width="300" height="550" xmlns="http://www.w3.org/2000/svg">
        <circle cx="150" cy="100" r="60" style="fill:red; stroke-width:3; stroke:rgb(0,0,0); fill-opacity:0.7"  />
    </svg>
    

    (note the fill:red)

    And this code:

        Image {
            id: image
            Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
            source: "qrc:/circle2.svg"
            visible: false // <== DON'T FORGET THIS LINE
        }
        MultiEffect {
            source: image
            anchors.fill: image
            colorization: 1.0
            colorizationColor: "blue"
        }
    

    And it works. So it's not a Qt problem; it's the way the .svg files are constructed.

    mzimmersM 1 Reply Last reply
    0
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    replied to mzimmers on last edited by mzimmers
    #4

    another update: further testing revealed that you can't just put a fill= in the path; it has to be:

    <path style="fill:#00ff00" ...
    

    and the fill value can't be "none;" it must be a color (either by name or by RGB value).

    This works on my original circle (though it's only filling the outline; I think I need to remove part of the path for it to fill the entire circle.

    It worked on the puppy too (though there are 3 paths in the puppy; you'd have to add it to all of them).

    So...I think we have our answer.

    1 Reply Last reply
    0
  • C Offline
    C Offline
    christofer
    wrote on last edited by christofer
    #5

    Thanks for the replies @mzimmers !

    You inspired me to experiment more. It turns out all I have to do is change the existing SVG fill from black to white.

    I changed...

    <g transform="translate(0.000000,1280.000000) scale(0.100000,-0.100000)"
    fill="#000000" stroke="none">
    

    to...

    <g transform="translate(0.000000,1280.000000) scale(0.100000,-0.100000)"
    fill="white" stroke="none">
    

    Result...
    Screen Shot 2023-04-04 at 6.00.26 AM.png

    The changes are in the GitLab project, tag qt-forum-post-02

    mzimmersM 1 Reply Last reply
    0
  • C christofer has marked this topic as solved on
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    replied to christofer on last edited by mzimmers
    #6

    @christofer interesting. I did some experimentation of my own on the puppy file, and it appears that the problem wasn't the use of the RGB format for specifying the color, but rather the fill of black, or indeed any color other than white (or #ffffff).

    EDIT: scratch the comment below -- I forgot my own advice of hiding the original image.

    As a side note, I also noticed that when using the Image inside a Layout, you can't use the anchors property, so the MultiEffect appear below (in the case of a ColumnLayout) the original image. My workaround was to put the Image and the MultiEffect in an Item, so I could use anchors, but there might be a more elegant way to accomplish this.

    ekkescornerE 1 Reply Last reply
    0
  • mzimmersM mzimmers referenced this topic on
  • ekkescornerE Offline
    ekkescornerE Offline
    ekkescorner Qt Champions 2016
    replied to mzimmers on last edited by ekkescorner
    #7

    @mzimmers tried to colorize a png
    my old code:

    Image {
        id: image
        ....
        ColorOverlay {
            id: colorOverlay
            anchors.fill: image
            source: image
            color: primaryColor
        }
    

    new code:

    Image {
            id: image
            ....    
    MultiEffect {
            id: colorOverlay
                source: image
                anchors.fill: image
                colorization: 1.0
                colorizationColor: primaryColor
            }
    

    But the Image isn't colorized.
    -----------edit: foundSolution

    1. separated Image and MultiEffect and placed both inside an Item
    2. then set visible false at Image
      result: not colorized, but found the reason
      the png was a black icon - changed this and used a white icon and now colorizing works.
      So this is different to QtQuickEffects and Qt 5.15

    ekke ... Qt Champion 2016 | 2024 ... mobile business apps
    5.15 --> 6.8 https://t1p.de/ekkeChecklist
    QMake --> CMake https://t1p.de/ekkeCMakeMobileApps

    1 Reply Last reply
    0
  • A Offline
    A Offline
    alvarosaes
    wrote on last edited by alvarosaes
    #8

    Hello, I also had this question so i asked directly via Qt support. I got this response:

    > Thank you for you response. So, ColorOverlayEffect from import
    > QtQuick.Studio.Effects 1.0 is not equivalent to this? I didnt have this
    > problem while using that effect
    
    Yeah, different effect:
    
    fragColor = vec4(mix(pixelColor.rgb/max(pixelColor.a, 0.00390625), color.rgb/max(color.a, 0.00390625), color.a) * pixelColor.a, pixelColor.a) * qt_Opacity;
    
    Compared to this for colorization:
    
    color.rgb = (color.rgb - 0.5 * color.a) * (1.0 + contrast) + 0.5 * color.a;
    color.rgb += brightness * color.a;
    float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
    float colorizationAlpha = colorization * colorizationColor.a;
    color.rgb = mix(color.rgb, gray * colorizationColor.rgb, colorizationAlpha);
    color.rgb = mix(vec3(gray), color.rgb, 1.0 + saturation);
    

    So i only see 2 solutions:

    • Convert all your svgs to fill white
    • Rollback to use ColorOverlayEffect

    @mzimmers @christofer @ekkescorner

    1 Reply Last reply
    1
  • S Offline
    S Offline
    srce
    wrote on last edited by srce
    #9

    Rather than converting pngs from black to white, setting brightness to 1 (in addition to colorize) should have a similar effect.

    M 1 Reply Last reply
    1
  • Q Offline
    Q Offline
    QKelteseth
    wrote on last edited by
    #10

    @srce thank you!!

    1 Reply Last reply
    0
  • M Offline
    M Offline
    MattP2
    replied to srce on last edited by MattP2
    #11

    @srce said in Qt6 color SVG using MultiEffect:

    Rather than converting pngs from black to white, setting brightness to 1 (in addition to colorize) should have a similar effect.

    This is the answer, a big thank you.

    So, visible: false, parent Item and color in svg are not required.
    This is working with any svg:

    Image {
        // image properties
        layer.enabled: true
        layer.effect: MultiEffect {
            brightness: 1.0
            colorization: 1.0
            colorizationColor: enabled ? Material.primaryTextColor : Material.secondaryTextColor
        }
    }
    
    1 Reply Last reply
    0
  • nicwainwrightN nicwainwright referenced this topic on

  • Login

  • Login or register to search.
  • First post
    Last post
0
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved