Recoloring a set of PNG icons

219 Views Asked by At

I have a set of icons in a .png format. The customer wants them in a different colour. I know they are from either glyphicons or fontawesome icon fonts, but I do not know how they were generated. I tried this command to recolour them, but bits of red are always left behind and increasing fuzz value has negative effects on other parts of image:

mogrify -fuzz 41% -fill "#5DBFAD" -opaque "#ea5648" *icon.png *arrow.png *rtl.png

Image before: Image before

Image after: Image after

Note: Look closely if you have a dark theme on, there is a second dark-grey icon over the coloured one.

I need either a way to get rid of these red artefacts or a way to generate these icons on my own with the colour of my choice (a full replacement in css is also an option, using the icon font, colouring it and animating). Also for an unknown reason some icons have the coloured one on top like this:

Coloured icon on top

Extra info: When hovered-over these icons transition a few pixels up/down to show the other icon. This is a part of a free nopCommerce theme: http://themes.nopaccelerate.com/themes/nopaccelerate-simplex-theme-3/?utm_source=nop&utm_medium=extension&utm_campaign=extension-directory

3

There are 3 best solutions below

0
GeeMack On BEST ANSWER

You can use ImageMagick to re-color just the bottom half of your input image with a command like this...

magick input.png -crop 1x2@ ^
   ( +clone -fill "#5DBFAD" -colorize 100 ) -delete 1 -append result.png

That isolates just the bottom half inside the parentheses, and uses "-colorize" to re-color the image without leaving the artifacts. Then it re-assembles the halves to complete the icon.

Unfortunately "-clone" is not an available option to "mogrify", so for a command like this you'd need to use just "magick" and a "for" loop in your command shell to process multiple images.

The command is in Windows syntax. For a *nix system change the continued-line caret "^" to a backslash "\" and escape the parentheses with backslashes "\(...\)".

Regarding the icons with the colored part on top instead of the bottom, ImageMagick can probably determine which end is colored, but it could get complicated. Maybe easier to sort them manually and process them in two groups. To color just the top half, add "-rotate 180" just after reading in the image and "-rotate 180" again before writing the result.

0
Raju Paladiya On

Hi Best way is ask support team for this As you using nopAccelerate's theme you can direct reach them at support(at)nopaccelerate.com or go to here and create support ticket with them.

0
Luk164 On

I ended up writing a simple program to do this, so I am posting the source here, but the @GeeMack's answer seems like a more elegant solution so I am accepting it.

My source code: Program.cs

using System;
using System.Drawing;
using System.IO;

namespace ColorReplacer
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"Supplied path: {args[0]}, from color: {args[1]} to color: {args[2]}");

            FileStream fs = new FileStream(args[0], FileMode.Open);
            var image = new Bitmap(fs);
            fs.Close();

            for (var i = 0; i < image.Width; i++)
            {
                for (var j = 0; j < image.Height; j++)
                {
                    var pixel = image.GetPixel(i, j);
                    if (pixel.R == ColorConverter.RfromHex(args[1]) && pixel.G == ColorConverter.GfromHex(args[1]) && pixel.B == ColorConverter.BfromHex(args[1]))
                    {
                        image.SetPixel(i, j, Color.FromArgb(pixel.A, ColorConverter.RfromHex(args[2]), ColorConverter.GfromHex(args[2]), ColorConverter.BfromHex(args[2])));
                    }
                }
            }

            image.Save(args[0]);
        }
    }
}

ColorConverter.cs

using System.Globalization;

namespace ColorReplacer
{
    public static class ColorConverter
    {
        public static int RfromHex(string color)
        {
            if (color.IndexOf('#') != -1)
                color = color.Replace("#", "");

            return int.Parse(color.Substring(0, 2), NumberStyles.AllowHexSpecifier);
        }

        public static int GfromHex(string color)
        {
            if (color.IndexOf('#') != -1)
                color = color.Replace("#", "");

            return int.Parse(color.Substring(2, 2), NumberStyles.AllowHexSpecifier);
        }

        public static int BfromHex(string color)
        {
            if (color.IndexOf('#') != -1)
                color = color.Replace("#", "");

            return int.Parse(color.Substring(4, 2), NumberStyles.AllowHexSpecifier);
        }
    }
}