Skip to content

Instantly share code, notes, and snippets.

@JohannesDeml
Last active May 12, 2024 02:02
Show Gist options
  • Save JohannesDeml/779b29128cdd7f216ab5000466404f11 to your computer and use it in GitHub Desktop.
Save JohannesDeml/779b29128cdd7f216ab5000466404f11 to your computer and use it in GitHub Desktop.
Batch convert images with inkscape on windows

Batch convert svg|pdf|eps|emf|wmf|ai|ps|cdr to eps|pdf|png|jpg|tiff|svg|ps|emf|wmf

Screenshot Batch converter for Windows using Inkscape with the command line
InkscapeBatchConvert is an easy to use solution to quickly convert all files of a folder to another type without the need to open Inkscape. The program uses Windows Batch scripting and will only work on Windows.
Tested with Inkscape 1.0.x - 1.3.x ✅ (The last version that supports Inkscape 0.9.x can be found here)

Usage

  1. Download _InkscapeBatchConvert.bat
  2. Put it in the folder where you have files you wish to convert (will also scan on all subfolders for files of input type).
  3. Then double click the file to start it.

Troubleshooting

Problem Solution
Windows blocks the program Right click the file → Properties → Unblock
Windows protected your PC Disable blocking
I can't convert EPS / PDF files. The program says it runs the conversion, but there are no files in the out folder. Make sure you have ghost script installed and added to your environment path. For more information read the Inkscape FAQ
Add ghostscript to path
Can't find Inkscape installation All common file paths are checked for the installation. If you haven't installed Inkscape download it here, otherwise you can also define your own path in the script by adding the next array element of inkscapePaths to the script
Can't find inkscape installation custom inkscape path
I'm missing a setting in the script, e.g. defined output width Have a look at the Commandline Documentation or read the inkscape help file inkscape --help and add the needed properties to the script
Inkscape help output Script change position
I'm missing a specific input or output type If inkscape supports those types, you can easily add them to the list in the script (search for validInput and validOutput)
Add input / output type
The files are saved to out\, but I would like to have it saved in the same directory or a subdirectory with a different name Just change the variable relativeOutputFolder - If you want to save the files to the same directory, set it to nothing (set relativeOutputFolder=)
Set subdirectory

Todo

Use shell or pipe to avoid starting inkscape for every file as pointed out by @vaifrax here. I would be very happy to get help for that 🙂

Credits

:: From https://gist.github.com/JohannesDeml/779b29128cdd7f216ab5000466404f11
:: Convert vector file formats in the current folder and their subsfolders
:: The variables in the beginning can be changed to your needs
:: Tested for Inkscape 1.0 - 1.3
@echo off
setlocal ENABLEDELAYEDEXPANSION
:: Define supported input file extensions
set validInput=svg pdf eps emf wmf ps ai cdr
:: Define supported output file extensions
:: All supported extnesions: [.dxf, .emf, .eps, .fxg, .gpl, .hpgl, .html, .jpg, .odg, .pdf, .png, .pov, .ps, .sif, .svg, .svgz, .tar, .tex, .tiff, .webp, .wmf, .xaml, .zip]
set validOutput=svg png tiff jpg webp pdf eps emf wmf ps cdr
:: Define relative output folder, if you want to write to the same folder set the var to an empty string
set relativeOutputFolder=out\
:: Possible paths to check for the installation
set "inkscapePaths[1]=C:\Program Files\Inkscape\bin\inkscape.com"
set "inkscapePaths[2]=C:\Program Files\Inkscape\bin\inkscape.exe"
set "inkscapePaths[3]=C:\Program Files\Inkscape\inkscape.com"
set "inkscapePaths[4]=C:\Program Files (x86)\Inkscape\bin\inkscape.com"
set "inkscapePaths[5]=C:\Program Files (x86)\Inkscape\bin\inkscape.exe"
set "inkscapePaths[6]=C:\Program Files (x86)\Inkscape\inkscape.com"
set "inkscapePaths[7]=%UserProfile%\scoop\apps\inkscape\current\bin\inkscape.exe"
set "inkscapePath="
set /a "pathIndex=1"
:: Find the inkscape installation path
:inkscapepath_loop_start
if defined inkscapePaths[%pathIndex%] (
set "currentPath=!inkscapePaths[%pathIndex%]!"
if exist "!currentPath!" (
:: found installation path
set "inkscapePath=!currentPath!"
goto :inkscapepath_loop_end
)
set /a "pathIndex+=1"
goto :inkscapepath_loop_start
) else (
echo Can't find Inkscape installation, aborting.
goto end
)
:inkscapepath_loop_end
:: Set the path to allow for spaces without any needed additional quotes
set inkscapePath="%inkscapePath%"
set validInputString=
(for %%a in (%validInput%) do (
set validInputString=!validInputString!, %%a
))
:: Remove the leading comma
set validInputString=%validInputString:~2%
set validOutputString=
(for %%a in (%validOutput%) do (
set validOutputString=!validOutputString!, %%a
))
:: Remove the leading comma
set validOutputString=%validOutputString:~2%
:: If this can't be run, then the version is an older one
FOR /F "tokens=* USEBACKQ" %%g IN (`%inkscapePath% --version`) do (SET "inkscapeVersion=%%g")
if "%inkscapeVersion%" EQU "" (
set inkscapeVersion=0.x
set /a inkscapeMajorVersion=0
) else (
set /a inkscapeMajorVersion=%inkscapeVersion:~9,1%
)
echo.
echo This script allows you to convert all files in this folder from one file type to another
echo Running with %inkscapeVersion% from %inkscapePath%
echo (type q to quit at any question)
echo.
set valid=0
echo Allowed file types for source: %validInputString%
:whileInNotCorrect
set /p sourceType=What file type do you want to use as a source?
if "%sourceType%" EQU "q" exit /b
for %%a in (%validInput%) do (
if "%%a"=="%sourceType%" (
set valid=1
goto inSet
)
)
if %valid% EQU 0 (
echo Invalid input! Please use one of the following: %validInputString%
goto :whileInNotCorrect
)
:inSet
echo.
set valid=0
echo Allowed file types for output: %validOutputString%
:whileOutNotCorrect
set /p outputType=What file type do you want to convert to?
if "%outputType%" EQU "q" exit /b
for %%a in (%validOutput%) do (
if "%%a"=="%outputType%" (
set valid=1
goto outSet
)
)
if %valid% EQU 0 (
echo Invalid input! Please use one of the following: %validOutputString%
goto :whileOutNotCorrect
)
:outSet
if "%outputType%" EQU "%sourceType%" (
echo Input and Output are the same, no point in doing anything. Exiting...
exit /b
)
echo.
:: Set DPI for exported file
:whileNotValidDpiNumber
set /p dpi=With what dpi should it be exported (e.g. 300)?
if "%dpi%" EQU "q" exit /b
IF %dpi% NEQ +%dpi% (
echo Invalid input! Please input an actual number.
goto :whilenotValidDpiNumber
)
echo.
:: count how many files we need to convert before converting!
set /a total=0
for /R %%i in (*.%sourceType%) do ( set /a total=total+1 )
echo Found %total% file(s) of type *.%sourceType% in the current folder (%~dp0)
echo.
:: Create output folder if it is set and does not exist
if not "!relativeOutputFolder!"=="" (
if not exist "!relativeOutputFolder!" mkdir "!relativeOutputFolder!"
)
set /a count=0
:: Running through all files found with the defined ending
if %inkscapeMajorVersion% NEQ 0 (
:: Inkscape 1.0 and newer
for /R %%i in (*.%sourceType%) do (
set /a count=count+1
echo %%i -^> %%~di%%~pi!relativeOutputFolder!%%~ni.%outputType% ^[!count!/%total%^]
%inkscapePath% --export-filename="%%~di%%~pi!relativeOutputFolder!%%~ni.%outputType%" --export-dpi=%dpi% "%%i"
)
)
echo.
echo %count% file(s) converted from %sourceType% to %outputType%! (Saved in out folder)
echo.
:end
pause
@JohannesDeml
Copy link
Author

@knightknight I'm quite sure inkscape is not found correctly in your case. I updated the script to also include the path for scoop as a possible location. Please download again and run it by double clicking (running through the terminal or command prompt should be possible as well).

@knightknight
Copy link

@JohannesDeml, perfecto worked!!

Something must have gone wrong when I copied & pasted the RAW code first time around.

It detected the Inkscape version Running with Inkscape 1.2.1 (9c6d41e410, 2022-07-14) from "C:\Users\<name>\scoop\apps\inkscape\current\bin\inkscape.exe" and I'm getting the output folder with converted .png files.

👍

@JohannesDeml
Copy link
Author

@knightknight Coolcool, glad it works now for you as well. Thanks for letting us know 🎉

@RobG73
Copy link

RobG73 commented Jan 19, 2023

Many thanks for this batch-file. It works perfectly in Windows 11.

I am producing multiple .svg files using a Python program and this library: https://github.com/RobG73/InkscapeFileMaker. Using a program to make the inkscape files means that I can make small changes to every file by changing the program. The problem is that I need to export/convert every svg file to .png before I can include them in a LibreOffice document.

Your program enables me to do this with one click. Brilliant! Thank you.

@JohannesDeml
Copy link
Author

Hi @RobG73 ,

thanks for you comment, glad to hear that the script helps you in your workflow 🥳

Copy link

ghost commented Feb 18, 2023

Hello. I just tried the batch file. Unfortunately, after converting an emf file to a png file, it removes the text contained in it for me. What can I do?
This is the png-file after convert:
1_SeiteL_Lichtgr___1
This ist the emf-file before convert:
1_SeiteL_Lichtgr___1

@JohannesDeml
Copy link
Author

Hi @wethlo448 ,

I tried reproducing the problem by creating an emf through Inkscape. I tried with both convert text to paths enabled and disabled, and in both cases the generated png included the text correctly.
inkscape_wOBQK4MW3h
Did you try to export the file file inkscape directly? And did this work? Did you also make sure to have the specific font installed? And are you using the latest inkscape version (1.2.2)?
If the answer to all of those is yes, please share a file, then I can try to reproduce it :)

Copy link

ghost commented Feb 19, 2023 via email

@JohannesDeml
Copy link
Author

Hi @wethlo448,

You replied on the gist (for which I can't see the attachment), I think you might have wanted to send me an email - You can do so by writing to public@deml.io :)

@db333385
Copy link

Hi -thanks for this script - is it possible to convert a PDF file that has multiple pages? So far I can only get it to produce the first page.

@JohannesDeml
Copy link
Author

@db333385 Out of the box: no. But inkscape does expose the option --pdf-page=PAGE which you could use to define which page should be exported. So you could modify the script to export a specific page or make a loop to export a range of pages. See also https://wiki.inkscape.org/wiki/index.php/Using_the_Command_Line

@db333385
Copy link

Thanks a lot for the reply - do you know how I would access the page count of a particular PDF so I could loop through the right amount of pages?

@JohannesDeml
Copy link
Author

@db333385 I don't think Inkscape exposes any api for that, but maybe you could use different tools - ChatGPT suggests pdfinfo:

FOR %%I IN (*.pdf) DO pdfinfo "%%I" | findstr Pages

You could just include that in the loop (but will need to install pdfinfo first on your machine with the folder added to your environment variables. You can find a download here: https://www.xpdfreader.com/pdfinfo-man.html

@allnightsnack
Copy link

Hi!
Totally new to commands, but I got this to convert my png to svg successfully, which is superawesome! But I do get the Inkscape pop-up "png bitmap image import" at every image, and it does not help that I mark the box "Do not ask again". What can I do to prevent this?

TIA

@JohannesDeml
Copy link
Author

Hi @allnightsnack,
First things first: Note that converting a png to an svg does not convert the image to a vector format, it results in an svg that has an embedded png file (maybe that is what you want, but I just want to make sure you're not surprised here).

I just checked with Inkscape v1.3 and added the png to the allowed input parameters and didn't have any popups. Try to download the latest version of inkscape and also the latest version of the above script (fixed problems with 1.3), and try to run it again, I hope it works this time for you :)

@myzenhost
Copy link

Can you show me how to use your file to mass convert but to NOT put it in a new OUT folder but in the same folder as original file?

@JohannesDeml
Copy link
Author

Hi @myzenhost,

I updated the script with a simple option at the very top of the script, change this

:: Define relative output folder, if you want to write to the same folder set the var to . (remove \out)
set relativeOutputFolder=.\out

to

:: Define relative output folder, if you want to write to the same folder set the var to . (remove \out)
set relativeOutputFolder=.

Then the files write into the same folder :)

@myzenhost
Copy link

thank you for adding it but it is adding the images to the root folder and not the same folder as the original files that reside in sub folders.

also are you able to add any support for multithreading etc to do the process faster? If not i understand.

@myzenhost
Copy link

it also seems to now create a out folder in the root directory only and all copies of the converted files go to that instead of the out folders it made in the original version that would be in the sub folders if the target files are in subfolders which was better.

@myzenhost
Copy link

Also I was able to add CDR to acceptable input filetypes in mine and it worked great both on Old CDRs and New. There are not many conversion software titles out there that can batch convert both old and new CDR files so I would recommend adding it as a standard option for your script as it is truly usefull and already supported :)

@JohannesDeml
Copy link
Author

Hi @myzenhost,
Thanks for the feedback. I changed the script support cdr as input and the folders now stay relative - if you want to export to the same folder just change line 15 to

set relativeOutputFolder=

also are you able to add any support for multithreading etc to do the process faster? If not i understand.

Using the shell command or piping was suggested before. If you want to implement that, I'm happy to take over your changes to the script.

@SHIFT969
Copy link

Thanks for the wonderful tool! However, it would've been great if it allowed for setting the dimensions of the png files. I have multiple svg files with different sizes and I want for the output images to have the same height (512px) since they are icons (dpi doesn't do the trick). Is there a way to implement this feature? Also, would it be possible to add a suffix to the output files' title?

Thanks again!

I tried it with my icons and if I choose 300 DPI, I get 1600x1600 image.
Divide 512 by 1600, get 0.32.
Then multiply 300 by 0.32, get 96.
Run the script with 96 DPI, get 512x512 images.

Hope that helps someone.

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