Skip to content

Instantly share code, notes, and snippets.

@MircoBabin
Last active March 21, 2025 08:28
Show Gist options
  • Save MircoBabin/d798f1f536aefb36b953781804e0bb9e to your computer and use it in GitHub Desktop.
Save MircoBabin/d798f1f536aefb36b953781804e0bb9e to your computer and use it in GitHub Desktop.
Convert SVG to Windows executable icon using ImageMagick
@echo off
setlocal
rem SvgToWindowsExecutableIcon.bat
rem Windows/OS used: Windows/11
rem ----------------------------------------------------
rem
rem Version 1.1 - released on friday 21 march 2025
rem
rem ----------------------------------------------------
rem Depends on ImageMagick https://imagemagick.org
rem Version used: ImageMagick 7.1.1-29 Q16-HDRI x64
rem ----------------------------------------------------
rem %1 is input svg filename, e.g. source.svg
rem %2 is full path to magick.exe. If empty or omitted, it is assumed magick.exe is in the path.
rem %3 may optionally be "grayscale" to produce a grayscale ico.
rem ----------------------------------------------------
rem
rem ----------------------------------------------------
rem MIT license
rem
rem Copyright (c) 2024 Mirco Babin
rem
rem Permission is hereby granted, free of charge, to any person
rem obtaining a copy of this software and associated documentation
rem files (the "Software"), to deal in the Software without
rem restriction, including without limitation the rights to use,
rem copy, modify, merge, publish, distribute, sublicense, and/or sell
rem copies of the Software, and to permit persons to whom the
rem Software is furnished to do so, subject to the following
rem conditions:
rem
rem The above copyright notice and this permission notice shall be
rem included in all copies or substantial portions of the Software.
rem
rem THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
rem EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
rem OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
rem NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
rem HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
rem WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
rem FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
rem OTHER DEALINGS IN THE SOFTWARE.
rem ----------------------------------------------------
rem
rem ----------------------------------------------------
rem Why:
rem There are lots of tools/snippets/online converters etc. to convert a .SVG file to an icon file.
rem But they did not provide an easy way to simply do it "good" for a Windows executable icon.
rem A Windows executable icon must contain some not-well-defined sizes and formats to be compatible across different Windows versions.
rem Sometime ago I created an icon for TiddlyWikiWatcher ( https://github.com/MircoBabin/TiddlyWikiWatcher ) that seems to work.
rem I wanted to use the same sizes&formats for a new icon.
rem That is when SvgToWindowsExecutableIcon.bat was born.
rem ----------------------------------------------------
set "svgSource=%~dpnx1"
set "icoOutput=%~dpn1.ico"
set magickExe=magick.exe
if not "%~2"=="" set magickExe=%~2
set svgGrayscale=false
if "%~3"=="grayscale" set svgGrayscale=true
set svgGrayscaledFilename=
set icoSources=
set tmpMagickCommandInput=
set tmpMagickCommandOutput=
set tmpMagickCommand=
:step_check_magick
if exist "%magickExe%" goto step_grayscale_svg
where /q "%magickExe%" >nul 2>&1
if errorlevel 1 goto step_magick_not_found
goto step_grayscale_svg
:step_magick_not_found
echo.
echo ImageMagick https://imagemagick.org magick.exe was not found.
echo "%magickExe%"
goto step_error
:step_grayscale_svg
if not "%svgGrayscale%"=="true" goto step_delete_output
echo [GRAYSCALE] --- begin ---
call :build_svgGrayscaledFilename "%svgSource%"
echo Create grayscaled svg in %svgGrayscaledFilename%
set tmpMagickCommandInput=%svgSource%
set tmpMagickCommandOutput=%svgGrayscaledFilename%
set tmpMagickCommand="%magickExe%" convert "%tmpMagickCommandInput%" -colorspace Gray "%svgGrayscaledFilename%"
call :magick_execute
if errorlevel 1 goto step_error
set icoSources=
set svgSource=%svgGrayscaledFilename%
echo.
echo [GRAYSCALE] --- end ---
echo.
goto step_delete_output
:step_delete_output
if not exist "%icoOutput%" goto step_resize
del /q "%icoOutput%" >nul 2>&1
if not exist "%icoOutput%" goto step_resize
echo Error deleting .ico outputfile: "%icoOutput%"
goto step_error
:step_resize
echo [RESIZE] --- begin ---
call :magickResize "%svgSource%" 16x16 bmp-4bit
if errorlevel 1 goto step_error
call :magickResize "%svgSource%" 16x16 bmp-8bit
if errorlevel 1 goto step_error
call :magickResize "%svgSource%" 16x16 bmp-32bit
if errorlevel 1 goto step_error
call :magickResize "%svgSource%" 20x20 bmp-32bit
if errorlevel 1 goto step_error
call :magickResize "%svgSource%" 24x24 bmp-32bit
if errorlevel 1 goto step_error
call :magickResize "%svgSource%" 32x32 bmp-4bit
if errorlevel 1 goto step_error
call :magickResize "%svgSource%" 32x32 bmp-8bit
if errorlevel 1 goto step_error
call :magickResize "%svgSource%" 32x32 bmp-32bit
if errorlevel 1 goto step_error
call :magickResize "%svgSource%" 40x40 bmp-32bit
if errorlevel 1 goto step_error
call :magickResize "%svgSource%" 48x48 bmp-8bit
if errorlevel 1 goto step_error
call :magickResize "%svgSource%" 48x48 bmp-32bit
if errorlevel 1 goto step_error
call :magickResize "%svgSource%" 64x64 bmp-32bit
if errorlevel 1 goto step_error
call :magickResize "%svgSource%" 256x256 png
if errorlevel 1 goto step_error
echo.
echo [RESIZE] --- end ---
echo.
:step_creating_ico
echo.
echo [CREATE ICO] ------------------------------------------------------------------
echo.
echo "%magickExe%" %icoSources% "%icoOutput%"
"%magickExe%" %icoSources% "%icoOutput%"
if exist "%icoOutput%" goto step_created_ico
echo.
echo .ico outputfile was not created: "%icoOutput%"
goto step_error
:step_created_ico
echo.
echo [IDENTIFY ICO] ----------------------------------------------------------------
echo.
"%magickExe%" identify "%icoOutput%"
echo.
echo.
echo Created: "%icoOutput%"
echo --- SUCCESS ---
exit /b 0
:step_error
echo.
echo !!! ERROR !!!
pause
exit /b 99
:build_svgGrayscaledFilename
set "svgGrayscaledFilename=%~dpn1-grayscale%~x1"
set "icoOutput=%~dpn1-grayscale.ico"
exit /b 0
:magickResize
rem %1 is source.svg
rem %2 is size e.g. 16x16
rem %3 is outputtype
set tmpMagickCommandInput=%~1
set tmpMagickCommandOutput=%~dpn1.%~2
set tmpMagickCommand="%magickExe%" convert
set tmpMagickCommand=%tmpMagickCommand% -size %~2
set tmpMagickCommand=%tmpMagickCommand% -background transparent
if "%~3"=="bmp-4bit" goto magickResize_bmp_4bit
if "%~3"=="bmp-8bit" goto magickResize_bmp_8bit
if "%~3"=="bmp-32bit" goto magickResize_bmp_32bit
if "%~3"=="png" goto magickResize_png
echo :magickResize - unknown output-type: %~3
exit /b 1
:magickResize_bmp_4bit
set tmpMagickCommand=%tmpMagickCommand% +dither -depth 4 -colors 16 -type palette
set tmpMagickCommandOutput=%tmpMagickCommandOutput%.4bit.bmp
set tmpMagickCommand=%tmpMagickCommand% "%tmpMagickCommandInput%" "%tmpMagickCommandOutput%"
goto magick_execute
:magickResize_bmp_8bit
set tmpMagickCommand=%tmpMagickCommand% +dither -depth 8 -colors 256 -type palette
set tmpMagickCommandOutput=%tmpMagickCommandOutput%.8bit.bmp
set tmpMagickCommand=%tmpMagickCommand% "%tmpMagickCommandInput%" "%tmpMagickCommandOutput%"
goto magick_execute
:magickResize_bmp_32bit
set tmpMagickCommand=%tmpMagickCommand% -depth 32
set tmpMagickCommandOutput=%tmpMagickCommandOutput%.32bit.bmp
set tmpMagickCommand=%tmpMagickCommand% "%tmpMagickCommandInput%" "%tmpMagickCommandOutput%"
goto magick_execute
:magickResize_png
set tmpMagickCommand=%tmpMagickCommand%
set tmpMagickCommandOutput=%tmpMagickCommandOutput%.png
set tmpMagickCommand=%tmpMagickCommand% "%tmpMagickCommandInput%" "%tmpMagickCommandOutput%"
goto magick_execute
:magick_execute
if exist "%tmpMagickCommandInput%" goto magick_execute1
echo :magickResize - inputfile does not exist: "%tmpMagickCommandInput%"
exit /b 2
:magick_execute1
if not exist "%tmpMagickCommandOutput%" goto magick_execute2
del /q "%tmpMagickCommandOutput%" > nul 2>&1
if not exist "%tmpMagickCommandOutput%" goto magick_execute2
echo :magickResize - error deleting outputfile: "%tmpMagickCommandOutput%"
exit /b 3
:magick_execute2
echo.
echo %tmpMagickCommand%
%tmpMagickCommand%
if exist "%tmpMagickCommandOutput%" goto magick_execute3
echo.
echo :magickResize - outputfile was not created: "%tmpMagickCommandOutput%"
exit /b 4
:magick_execute3
"%magickExe%" identify "%tmpMagickCommandOutput%"
set icoSources=%icoSources% "%tmpMagickCommandOutput%"
exit /b 0
@MircoBabin
Copy link
Author

  1. Attention: when saving file from GitHub, convert the line ending to Windows (CR LF)! Otherwise strange errors will happen like "label xxxx not found".

  2. The grayscale command SvgToWindowsExecutableIcon.bat icon.svg "" "grayscale" produces a warning "magick.exe: Cannot write image with defined png:bit-depth or png:color-type. `' @ warning/png.c/MagickPNGWarningHandler/1526.", but does output an ico file.

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