Home > Blockchain >  ImageMagick convert black image into a different colour
ImageMagick convert black image into a different colour

Time:05-28

I'm trying to convert a black SVG image into a coloured one. i.e replace black with a given colour. I've tried:

convert -resize 256x256\> -fill 'red' original.svg -opaque black new.png

This kind of works:

enter image description here

As you can see though, it has a black border still. How do I get rid of that?

I tried to upload the original SVG, but it won't let me (doesn't accept the format). But this is how it looks when I just do a straight:

convert original.svg new.png

enter image description here

UPDATE: I just found I can set the fill and border using in the main SVG:

<svg stroke="red" fill="red" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512">

But thats not ideal, as I would need to open the SVG, edit with a regex to the values I want, save it, and then finally do the conversion - so a bit long winded :)

The SVG I'm testing it with is:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M633.82 458.1L494.97 350.78c.52-5.57 1.03-11.16 1.03-16.87 0-111.76-99.79-153.34-146.78-311.82-7.94-28.78-49.44-30.12-58.44 0-15.52 52.34-36.87 91.96-58.49 125.68L45.47 3.37C38.49-2.05 28.43-.8 23.01 6.18L3.37 31.45C-2.05 38.42-.8 48.47 6.18 53.9l588.36 454.73c6.98 5.43 17.03 4.17 22.46-2.81l19.64-25.27c5.41-6.97 4.16-17.02-2.82-22.45zM144 333.91C144 432.35 222.72 512 320 512c44.71 0 85.37-16.96 116.4-44.7L162.72 255.78c-11.41 23.5-18.72 48.35-18.72 78.13z"/></svg>

UPDATE 2:

Ok, a REALLY dirty hack - but seems to do the trick. In my script, I'm now cloning the SVG into a temp file, running sed on it to change the fill/stroke colour, and then converting into a PNG at full size:

cp youtube-square.svg foo.svg
sed -i 's/<svg /<svg stroke="green" fill="green" /g' foo.svg
convert foo.svg foo.png

A bit clunky for my liking, but it seems to work :)

CodePudding user response:

In Imagemagick, you can change your black SVG to a red PNG as follows. Here I use your black.png since you have not provided the black.svg file. The following is Unix syntax of Imagemagick.

enter image description here

convert black.png \
\( -clone 0 -fill red -colorize 100 \) \
\( -clone 0 -negate \) \
-compose over -composite \
black2red.png

enter image description here

CodePudding user response:

You can do an XSL transformation on the SVG before converting with ImageMagic.

Given XML (original.svg):

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512">
  <!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) -->
  <path d="M633.82 458.1L494.97 350.78c.52-5.57 1.03-11.16 1.03-16.87 0-111.76-99.79-153.34-146.78-311.82-7.94-28.78-49.44-30.12-58.44 0-15.52 52.34-36.87 91.96-58.49 125.68L45.47 3.37C38.49-2.05 28.43-.8 23.01 6.18L3.37 31.45C-2.05 38.42-.8 48.47 6.18 53.9l588.36 454.73c6.98 5.43 17.03 4.17 22.46-2.81l19.64-25.27c5.41-6.97 4.16-17.02-2.82-22.45zM144 333.91C144 432.35 222.72 512 320 512c44.71 0 85.37-16.96 116.4-44.7L162.72 255.78c-11.41 23.5-18.72 48.35-18.72 78.13z"/>
</svg>

And the following XSL where I add a fill and stroke attribute to <svg> (convert.xsl):

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"
  exclude-result-prefixes="svg">
  <xsl:template match="svg:svg">
    <svg>
      <xsl:attribute name="fill">
        <xsl:value-of select="'red'"/>
      </xsl:attribute>
      <xsl:attribute name="stroke">
        <xsl:value-of select="'none'"/>
      </xsl:attribute>
      <xsl:for-each select="@*">
        <xsl:attribute name="{name()}">
          <xsl:value-of select="."/>
        </xsl:attribute>
      </xsl:for-each>
      <xsl:copy-of select="node()"/>
    </svg>
  </xsl:template>
</xsl:stylesheet>

This command:

xsltproc convert.xsl original.svg | convert - new.png

Will pipe the transformed SVG into ImageMagic and generate the PNG.

You can also use parameters in XSL, so here is a variation of the above:

A parameter is added to the XSL.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"
  exclude-result-prefixes="svg">

  <xsl:param name="fill" select="'red'" />
  
  <xsl:template match="svg:svg">
    <svg>
      <xsl:attribute name="fill">
        <xsl:value-of select="$fill"/>
      </xsl:attribute>
      <xsl:attribute name="stroke">
        <xsl:value-of select="'none'"/>
      </xsl:attribute>
      <xsl:for-each select="@*">
        <xsl:attribute name="{name()}">
          <xsl:value-of select="."/>
        </xsl:attribute>
      </xsl:for-each>
      <xsl:copy-of select="node()"/>
    </svg>
  </xsl:template>
</xsl:stylesheet>

And using the command:

xsltproc --stringparam fill green convert.xsl original.svg | convert - new.png

can change the fill of the PNG (and SVG) to green.

  • Related