0

Related to my other question, I need to convert my SVG to a 16-bit TIFF, which seems to be more complicated than expected. So I wanted to check Photoshop and Gimp, but they both (along with Figma) don't render my SVG correctly, so I wonder if anything is wrong with my code (here a simple example file, the original is basically the same just with a lot more rectangles):

<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000" viewBox="0 0 1000 1000">
  <defs>
    <linearGradient id="g">
      <stop offset="0%" stop-color="#0f0"></stop>
      <stop offset="50%" stop-color="#000"></stop>
      <stop offset="100%" stop-color="#0f0"></stop>
    </linearGradient>
    <linearGradient id="b" gradientTransform="rotate(90)">
      <stop offset="0%" stop-color="#00f"></stop>
      <stop offset="50%" stop-color="#000"></stop>
      <stop offset="100%" stop-color="#00f"></stop>
    </linearGradient>
  </defs>
  <rect x="0" y="0" width="1000" height="1000" fill="#fff"></rect>
  <g>
    <rect x="100" y="100" width="300" height="300" fill="url(#g)"></rect>
    <rect x="600" y="600" width="300" height="300"  fill="url(#g)"></rect>
  </g>
  <g style="mix-blend-mode:screen">
    <rect x="100" y="100" width="300" height="300" fill="url(#b)"></rect>
    <rect x="600" y="600" width="300" height="300"  fill="url(#b)"></rect>
  </g>
</svg>

This is what it should look like (converted to PNG by CloudConvert): In Photoshop and Gimp, only the blue layer renders, so it seems like the blend mode is ignored? In Figma (not that important for my case, but still) there seems to be a different problem with the gradient coordinates. But the browser displays it correctly, also CloudConvert seems to be fine with it.

So is this a problem with my code and the browser is just very forgiving, or are the SVG modules of Photoshop and Gimp broken?

Maybe the style needs to be applied to the individual <rects>s? But MDN says

Transformations applied to the <g> element are performed on its child elements, and its attributes are inherited by its children.

so it should be fine?

7
  • Not all features are supported by all renderers. The mix-blend-mode:screen CSS property is definitely the culprit here. Please note that it's not part of any SVG specification. The reason some browsers support it is because they already support it for regular HTML elements and just enabled it for SVG elements as well, even though they are not required to by the spec.
    – Xrott
    Mar 5, 2023 at 12:19
  • Ah, thanks a lot, that makes sense. So does that mean the only vector graphics formats which fully support gradients and blend modes are the proprietary ones, like Adobe Illustrator?
    – fweth
    Mar 5, 2023 at 12:34
  • The more "proper" way to use blend modes in SVG is by using filters (<feBlend>). It's a little more involved and is not guaranteed to be supported everywhere either, though. Especially if you want to blend objects with other objects in the background (using BackgroundImage as the source). I can write a full answer explaining how, if you want.
    – Xrott
    Mar 5, 2023 at 12:52
  • Ah no, that's not necessary I think, I can read into it! Also, as somebody else mentioned, ImageMagick seems to have no problem with my SVG, so that would be ideal since I prefer online tools or command line tools over full desktop applications like GIMP or Inkscape. But somehow I can't convert the SVG to 16-bit color TIFF in ImageMagick :/
    – fweth
    Mar 5, 2023 at 12:55
  • I dont think there is a implementation of vector sotware that would render gradients at higher bit depths than 8 bit per channel. To be honest the entire vector format ecosystem is not entirely dependable for a lot of things. Simply when you do a defeered render you gain the same problems as programmers have generally in their platform support. Features are arbitrarily supported.
    – joojaa
    Mar 6, 2023 at 14:54

2 Answers 2

1

Not sure what's up there, but your SVG fails to render properly in Illustrator, Inkscape, GIMP and Photoshop.

I messed around with it a little in Inkscape, ungrouping and rearranging a bit.

Try this one

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   width="1000"
   height="1000"
   viewBox="0 0 1000 1000"
   version="1.1"
   id="svg2281"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg">
  <defs
     id="defs2265">
    <linearGradient
       id="g">
      <stop
         offset="0%"
         stop-color="#0f0"
         id="stop2251" />
      <stop
         offset="50%"
         stop-color="#000"
         id="stop2253" />
      <stop
         offset="100%"
         stop-color="#0f0"
         id="stop2255" />
    </linearGradient>
    <linearGradient
       id="b"
       gradientTransform="rotate(90)">
      <stop
         offset="0%"
         stop-color="#00f"
         id="stop2258" />
      <stop
         offset="50%"
         stop-color="#000"
         id="stop2260" />
      <stop
         offset="100%"
         stop-color="#00f"
         id="stop2262" />
    </linearGradient>
    <linearGradient
       xlink:href="#g"
       id="linearGradient2285"
       x1="100"
       y1="100"
       x2="400"
       y2="100"
       gradientUnits="userSpaceOnUse" />
    <linearGradient
       xlink:href="#g"
       id="linearGradient2287"
       x1="600"
       y1="600"
       x2="900"
       y2="600"
       gradientUnits="userSpaceOnUse" />
    <linearGradient
       xlink:href="#b"
       id="linearGradient2291"
       x1="100"
       y1="100"
       x2="400"
       y2="100"
       gradientUnits="userSpaceOnUse"
       gradientTransform="translate(1.8675781e-5,-500)" />
    <linearGradient
       xlink:href="#b"
       id="linearGradient2293"
       x1="600"
       y1="600"
       x2="900"
       y2="600"
       gradientUnits="userSpaceOnUse"
       gradientTransform="translate(0,-1500)" />
  </defs>
  <rect
     style="fill:#ffffff;fill-opacity:1;stroke-width:5.29134;paint-order:markers fill stroke;stop-color:#000000"
     id="rect2911"
     width="1000"
     height="1000"
     x="0"
     y="0" />
  <rect
     x="100"
     y="100"
     width="300"
     height="300"
     fill="url(#g)"
     id="rect2269"
     style="fill:url(#linearGradient2285)" />
  <rect
     x="600"
     y="600"
     width="300"
     height="300"
     fill="url(#g)"
     id="rect2271"
     style="fill:url(#linearGradient2287)" />
  <rect
     x="600"
     y="-900"
     width="300"
     height="300"
     fill="url(#b)"
     id="rect2277"
     style="mix-blend-mode:screen;fill:url(#linearGradient2293)"
     transform="rotate(90)" />
  <rect
     x="100"
     y="-400"
     width="300"
     height="300"
     fill="url(#b)"
     id="rect2275"
     style="mix-blend-mode:screen;fill:url(#linearGradient2291)"
     transform="rotate(90)" />
</svg>

Tested in Illustrator (failed, doesn't seem to see the blending modes), Inkscape (works), GIMP (works) and Photoshop (failed, same problem as Illustrator), and Firefox (works) and Chrome (works)

Blending modes can be problematic in SVG rendering, to be honest I tend to avoid using them at all. Excessive grouping can also be an issue. I suspect a combination of these is responsible for the issue. Adobe doesn't really keep up with SVG standards, but you might be able to use Illustrator to rearrange it and get something to work with Adobe software.

4
  • Renders fine for me in InkScape...
    – xenoid
    Mar 5, 2023 at 11:19
  • Thank you! I wonder if gradientUnits="userSpaceOnUse" is really needed, because it would make the math in my SVGs more complicated. I'll check it out, hopefully it suffices to just put the blend mode on the individual <rect>s! It's really unfortunate that there exists apparently no simple, foolproof way to convert SVGs into 16-bit TIFF or PNG, could even be some command line tool. I'll have to check ImageMagick, maybe they are doing what I'm looking for!
    – fweth
    Mar 5, 2023 at 11:20
  • @xenoid - I'm on Inkscape 1.2.2, Win10. First time I opened the original SVG, didn't work. I tried it again, and then it worked, then I tried it a third time, didn't work. It's odd. Not sure what's up there.
    – Billy Kerr
    Mar 5, 2023 at 11:35
  • @fweth Maybe not needed. Inkscape adds attributes that are unnecessary sometimes. Try it and see
    – Billy Kerr
    Mar 5, 2023 at 11:53
1

To add to your list: renders as you expect in Inkscape (v0.92) and Firefox. Renders as a Blue-Black-Blue vertical gradient in Gimp and Gwenview.

ImageMagick converts it without problem to TIFF or PNG:

convert gradient.svg gradient.tif

enter image description here

1
  • Ah cool, many thanks! I just tried ImageMagick online so far (as I use ChromeOS, hence no command line) and it gave me an error, probably because SVGs could potentially invoke JavaScript, so I'll try it on GitPod or somewhere on the cloud!
    – fweth
    Mar 5, 2023 at 11:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.