Skip to content

Instantly share code, notes, and snippets.

@MircoBabin
Created March 8, 2024 15:53
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.0 - released on friday 8 march 2024
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 ----------------------------------------------------
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 icoSources=
set tmpMagickCommandInput=
set tmpMagickCommandOutput=
set tmpMagickCommand=
:step_check_magick
if exist "%magickExe%" goto step_delete_output
where /q "%magickExe%" >nul 2>&1
if errorlevel 1 goto step_magick_not_found
goto step_delete_output
:step_magick_not_found
echo.
echo ImageMagick https://imagemagick.org magick.exe was not found.
echo "%magickExe%"
goto step_error
: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
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
:step_creating_ico
echo.
echo.
echo.
echo.
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.
echo.
echo.
echo.
"%magickExe%" identify "%icoOutput%"
echo.
echo.
echo Created: "%icoOutput%"
echo --- SUCCESS ---
exit /b 0
:step_error
echo.
echo !!! ERROR !!!
pause
exit /b 99
: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
goto :magickResize_execute
:magickResize_bmp_8bit
set tmpMagickCommand=%tmpMagickCommand% +dither -depth 8 -colors 256 -type palette
set tmpMagickCommandOutput=%tmpMagickCommandOutput%.8bit.bmp
goto :magickResize_execute
:magickResize_bmp_32bit
set tmpMagickCommand=%tmpMagickCommand% -depth 32
set tmpMagickCommandOutput=%tmpMagickCommandOutput%.32bit.bmp
goto :magickResize_execute
:magickResize_png
set tmpMagickCommandOutput=%tmpMagickCommandOutput%.png
goto :magickResize_execute
:magickResize_execute
if exist "%tmpMagickCommandInput%" goto magickResize_execute1
echo :magickResize - inputfile does not exist: "%tmpMagickCommandInput%"
exit /b 2
:magickResize_execute1
if not exist "%tmpMagickCommandOutput%" goto magickResize_execute2
del /q "%tmpMagickCommandOutput%" > nul 2>&1
if not exist "%tmpMagickCommandOutput%" goto magickResize_execute2
echo :magickResize - error deleting outputfile: "%tmpMagickCommandOutput%"
exit /b 3
:magickResize_execute2
set tmpMagickCommand=%tmpMagickCommand% "%tmpMagickCommandInput%" "%tmpMagickCommandOutput%"
echo.
echo %tmpMagickCommand%
%tmpMagickCommand%
if exist "%tmpMagickCommandOutput%" goto magickResize_execute3
echo.
echo :magickResize - outputfile was not created: "%tmpMagickCommandOutput%"
exit /b 4
:magickResize_execute3
"%magickExe%" identify "%tmpMagickCommandOutput%"
set icoSources=%icoSources% "%tmpMagickCommandOutput%"
exit /b 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment