Skip to content

Instantly share code, notes, and snippets.

@ykarikos
Created June 7, 2012 22:17
Show Gist options
  • Save ykarikos/2892009 to your computer and use it in GitHub Desktop.
Save ykarikos/2892009 to your computer and use it in GitHub Desktop.
Convert png to svg using imagemagick and potrace
#!/bin/bash
if [ "$1" == "" ]; then
echo Usage: $0 pngfile
exit 0;
fi
FILE=`basename $1 .png`
if [ ! -e $FILE.png ]; then
echo $FILE.png does not exist
exit 1;
fi
convert $FILE.png $FILE.pnm
potrace -s -o $FILE.svg $FILE.pnm
rm $FILE.pnm
@RahulSDeshpande
Copy link

Can you please reply me with the code (.bat file) for Windows version??

Copy link

ghost commented Apr 30, 2015

Wow thanks for this! Really useful <3

@gonzafirewall
Copy link

@diadzine
Copy link

Nice script! I love it ;)

@eriksape
Copy link

with alpha channel to white

convert $FILE.png -fx 'a==0 ? white : u' $FILE.pnm

@rjpeart
Copy link

rjpeart commented Mar 8, 2017

Keeping alpha channel as white with the above didn't work for me. Instead I used

convert $FILE.png -background White -alpha Background $FILE.pnm

@Pamblam
Copy link

Pamblam commented Jun 12, 2018

didn't have potrace on my mac.. installation directions here: http://macappstore.org/potrace/

@willinspire
Copy link

I wrote an alternative in bash that provides error handling, auto installation of missing packages, and optional verbosity...

#! /bin/bash
################################################################################
#                                  _____                
#                                 / __  \               
#               _ __  _ __   __ _ `' / /'_____   ____ _ 
#              | '_ \| '_ \ / _` |  / / / __\ \ / / _` |
#              | |_) | | | | (_| |./ /__\__ \\ V / (_| |
#              | .__/|_| |_|\__, |\_____/___/ \_/ \__, |
#              | |           __/ |                 __/ |
#              |_|          |___/                 |___/ 
#
################################################################################
#------------------------------------------------------------------------------#
#
# SCRIPT NAME:      png2svg.sh
#
# DESCRIPTION:      Perform basic conversion of PNG images into SVG format
#
# MODIFIED DATE:    20181020
#
# SCRIPT AUTHOR:    h8rt3rmin8r (for ResoNova.com)
#
# SOURCE CODE:      bit.ly/png2svg-sh
# 
# USAGE:
#
#      Save this script locally as "png2svg.sh" and make it executable:
#        sudo chmod +x png2svg.sh
#
#      Run the script in the following manner:
#        ./png2svg.sh <file.png>
#
#      This script can be run without verbosity with the following:
#        sudo ./png2svg.sh --silent <file.png>
#
#      Enable this script to have global execution availability by placing it 
#      into /usr/local/bin (or somewhere else in your user's PATH). By doing
#      this, you can call "png2svg.sh" from anywhere on the system.
#
# LICENSE:
#
#      Copyright 2018 ResoNova International Consulting, LLC
#
#      Licensed under the Apache License, Version 2.0 (the "License");
#      you may not use this file except in compliance with the License.
#      You may obtain a copy of the License at
#
#          http://www.apache.org/licenses/LICENSE-2.0
#
#      Unless required by applicable law or agreed to in writing, software
#      distributed under the License is distributed on an "AS IS" BASIS,
#      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#      See the License for the specific language governing permissions and
#      limitations under the License.
#
#------------------------------------------------------------------------------#
# VARIABLE DECLARATIONS & SET PIPEFAIL
set -Eeo pipefail
DEPENDS=( "convert" "curl" "dos2unix" "potrace" )
DEPENDS_REQ=""; V_X=""; V_S=""; INPUT_X=""; INPUT_Y=""
INFO_SRC="https://pastebin.com/raw/VAnFpDLH"
VB_00="Beginning PNG conversion process. Please wait..."
VB_01="ERROR: A valid PNG image was not detected in your input parameters!"
VB_02="Please try again"
VB_03=" USAGE EXAMPLES: "
VB_04="    [ Verbose (Slow) ]  -->  ./png2svg.sh <file.png>"
VB_04B="    [ Piped Input v1 ]  -->  echo <file.png> | ./png2svg.sh"
VB_05="    [ Silent (Fast)  ]  -->  ./png2svg.sh --silent <file.png>"
VB_05B="    [ Piped Input v2 ]  -->  echo <file.png> | ./png2svg.sh --silent"
VB_06="    [ Usage Examples ]  -->  ./png2svg.sh --help"
VB_07="    [ General Info   ]  -->  ./png2svg.sh --info"
VB_08="ERR: Missing required package: "
VB_09="The following required packages are not installed on your system: "
VB_10="Terminating file conversion process."
VB_11="Done!"

#------------------------------------------------------------------------------#
# FUNCTION DECLARATIONS

function inputstream() {
    # Write all incoming data into an array, "INST", to allow for both
    # interactive and piped inputs in parent functions
    INST=""
    if [ -t 0 ]
        then local IN=( $(echo -n "$@") )
        else local IN=( $(</dev/stdin) $(echo -n "$@") )
    fi
    export INST=( $(echo ${IN[@]}) ); return
}

function n_tc() {
    # Colorize text outputs
    inputstream "$@"; local COLOR_FILTER=$(echo ${INST[@]})
    echo -e "\e[34m${COLOR_FILTER}\e[39m"; return
}

function vb_out() {
    # Output verbosity function
    echo $(n_tc "[$0]")" $@"; return
}

function depends_check() {
    # Make sure necessary software packages are present
    TEST_A=$("$1" --version > /dev/null 2>&1; echo -n $?)
    TEST_B=$("$1" -version > /dev/null 2>&1; echo -n $?)
    if [[ ! "${TEST_A}" == "0" && ! "${TEST_B}" == "0" ]];
        then echo "FALSE"
        else echo "TRUE"
    fi; return
}

function depends() {
    # Core dependancy checking loop
    for i in ${DEPENDS[@]};
    do
        case $(depends_check "$i") in
            FALSE) vb_out "${VB_08}$i"; DEPENDS_REQ+=( "$i" ) ;;
        esac
    done
    if [[ $(echo "${DEPENDS_REQ[@]}") =~ [A-Za-z0-9] ]];
    then
        vb_out "${VB_09}"
        for i in "${DEPENDS_REQ[@]}"; do n_tc "$i"; done
        echo; read -p "Would you like to install them? [y/n]: " -n 1 -r
        echo "" # insert new line
        if [[ $REPLY =~ ^[Yy]$ ]];
        then
            clear; echo $(vb_out "Installing ${DEPENDS_REQ[@]}")" Please wait..."
            sudo apt-get update
            for i in ${DEPENDS_REQ[@]}; do sudo apt-get install -y $i; done; clear
        else
            vb_out "${VB_10}"; exit 1
        fi
    fi
    return
}

function help_p2s() {
    # Print the png2svg help text
    echo; echo "${VB_03}"; echo
    echo "${VB_04}"; echo "${VB_04B}"
    echo "${VB_05}"; echo "${VB_05B}"
    echo "${VB_06}"; echo "${VB_07}"
    echo; return
}

#------------------------------------------------------------------------------#
# EXECUTE CORE OPERATIONS

inputstream "$@"; INPUT_VARS=( $(echo ${INST[@]}) )
case "$1" in
    -h|-help|--help) help_p2s; exit 0 ;;
    -i|-info|--info)
        depends; curl -s ${INFO_SRC} | dos2unix; echo; exit 0
        ;;
    -q|--quiet|-quiet|-s|--silent|-silent)
        V_X="/dev/null"; V_S="sleep 0"
        ;;
    *|'')
        if [[ "x${INPUT_VARS}" == "x" ]]; then help_p2s; exit 0
            else V_X="/dev/stdout"; V_S="sleep 0.5"; fi
        ;;
esac

depends; vb_out ${VB_00} &>${V_X}; ${V_S}

if [[ $(echo "${#INPUT_VARS[@]}") -gt 1 ]];
then
    touch .tempfile; INPUT_T=".tempfile"
    for i in "${INPUT_VARS[@]}";
    do
        if [[ -f "$i" && "$i" =~ \.png$ ]]; then echo -n "$i" > ${INPUT_T}; fi
    done
    INPUT_Y=$(cat ${INPUT_T})
    if [[ "x${INPUT_Y}" == "x" ]];
    then
        vb_out "${VB_01}" &>${V_X}; vb_out "${VB_02}" &>${V_X}
        help_p2s &>${V_X}; ${V_S}; exit 1
    else
        convert -flatten "${INPUT_Y}" "temp.ppm" &>${V_X}; ${V_S}
        potrace -s "temp.ppm" -o "${INPUT_Y%.*}.svg" &>${V_X}; ${V_S}
        rm temp.ppm &>/dev/null; rm ${INPUT_T} &>/dev/null
        vb_out "${VB_11}" &>${V_X}; ${V_S}
    fi
    exit 0
else
    INPUT_1=$(if [[ -f ${INPUT_VARS} && ${INPUT_VARS} =~ \.png$ ]]; then echo -n TRUE; else echo -n; fi)
    if [[ "x${INPUT_1}" == "x" ]];
    then
        vb_out "${VB_01}" &>${V_X}; vb_out "${VB_02}" &>${V_X}
        help_p2s &>${V_X}; ${V_S}; exit 1
    else
        convert -flatten "${INPUT_VARS}" "temp.ppm" &>${V_X}; ${V_S}
        potrace -s "temp.ppm" -o "${INPUT_VARS%.*}.svg" &>${V_X}; ${V_S}
        rm temp.ppm &>/dev/null; vb_out "${VB_11}" &>${V_X}; ${V_S}
    fi
    exit 0
fi

################################################################################
                                                   #                           # 
                                                   #  "think outside the box"  # 
                                                   #                           # 
                                                   #     ($) ¯\_(ツ)_/¯ (฿)    # 
                                                   #                           # 
                                                   #############################

@ouestdarq
Copy link

hello, noob question... Im running zsh in mac instead of bash... png2svg.sh with the !#/bin/bash shebang works; why?
and why does it not work if I change the shebang to zsh one and the ext to zsh? thnx

@ykarikos
Copy link
Author

ykarikos commented Apr 15, 2020

hello, noob question... Im running zsh in mac instead of bash... png2svg.sh with the !#/bin/bash shebang works; why?
and why does it not work if I change the shebang to zsh one and the ext to zsh? thnx

Hi @Wiruu! The !#/bin/bash means that the script will always be run in bash. The script syntax is bash, not zsh and that's why it would not work with !#/bin/zsh. The filename extension does not affect how it is run. I hope this helps!

@ouestdarq
Copy link

does a lot thnx...

@myselfhimself
Copy link

You may struggle if you do not apply high or low pass filters first. See http://potrace.sourceforge.net/mkbitmap.html

@AntumDeluge
Copy link

AntumDeluge commented Dec 31, 2020

Alternate command: convert infile.png pnm:- | potrace -s -o outfile.svg

@ykarikos
Copy link
Author

Alternate command: convert infile.png pnm:- | potrace -s -o outfile.svg

Nice one! Thanks!

@odmro
Copy link

odmro commented Dec 28, 2021

convert -alpha remove FILENAME.png FILENAME.svg

For all files in directory:
for i in *.png ; do convert -alpha remove "$i" $(echo $i | sed s/png/svg/) ; done

@MaydayGD
Copy link

Hi, I am trying to convert multiple full-colored PNG to SVG. I use PC. I have Potrace and Inkscape installed. What do I need to do to get this to work on my computer? What does "make it executable" mean? Thank you.

@AntumDeluge
Copy link

Hi, I am trying to convert multiple full-colored PNG to SVG. I use PC. I have Potrace and Inkscape installed. What do I need to do to get this to work on my computer? What does "make it executable" mean? Thank you.

This is a shell script for Unix/Linux/Posix systems. "make it executable" means doing the following:

$ chmod +x png2svg.sh

If you are on a Windows system, it doesn't mean anything as Windows filesystem doesn't support setting executable bit.

Windows doesn't have a Posix shell. So you won't be able to use this script unless you have an environment like MSYS2 or Cygwin installed.

@MiaLinlinLu
Copy link

convert infile.png pnm:- | potrace -s -o outfile.svg

Hi, I have a question. When I convert it, it converted a RGB image to a BlackWhite SVG. How could I correct this?
thank you!

@krashnakant
Copy link

Cant convert coloured PNG to SVG, produced svgs are BW

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment