Sergio
Sergio

Reputation: 931

Svg to png many files conversion using Inkscape from batch file

I have a folder containing many svg files and I would like to convert them to png files using inkscape with a batch script (Windows 10 *.bat file). the following script works correctly for a single file but, how to iterate the same command for hundreds of files inside a directory?

PATH = "C:\Program Files\Inkscape"

inkscape myfile.svg --export-png=myfile.png

Upvotes: 5

Views: 8829

Answers (3)

5andr0
5andr0

Reputation: 2018

@echo off
for %%i in ("%~dp0*.svg") do (
    echo %%i to %%~ni.png
    "C:\Program Files\Inkscape\bin\inkscape.exe" --export-type="png" "%%i"
)

Additional options for export are listed in this Wiki page, and in the man page (official documentation): in particular, you can set the DPI, height/width, what zone you export, etc.

To speed things up by utilizing all of your logic cores, you can use this multitasking approach:
Parallel execution of shell processes

@echo off
setlocal enableDelayedExpansion

:: Define the command that will be run to obtain the list of files to process
set listCmd=dir /b /a-d "%~dp0*.svg"

:: Define the command to run for each file, where "%%F" is an iterated file name from the list
::   something like YOUR_COMMAND -in "%%F" -out "%%~nF.ext"
set runCmd=""C:\Program Files\Inkscape\bin\inkscape.exe" --export-type="png" "%%F""

:: Define the maximum number of parallel processes to run.
set "maxProc=%NUMBER_OF_PROCESSORS%"

::---------------------------------------------------------------------------------
:: The remainder of the code should remain constant
::

:: Get a unique base lock name for this particular instantiation.
:: Incorporate a timestamp from WMIC if possible, but does not fail if
:: WMIC not available. Also incorporate a random number.
  set "lock="
  for /f "skip=1 delims=-+ " %%T in ('2^>nul wmic os get localdatetime') do (
    set "lock=%%T"
    goto :break
  )
  :break
  set "lock=%temp%\lock%lock%_%random%_"

:: Initialize the counters
  set /a "startCount=0, endCount=0"

:: Clear any existing end flags
  for /l %%N in (1 1 %maxProc%) do set "endProc%%N="

:: Launch the commands in a loop
  set launch=1
  for /f "tokens=* delims=:" %%F in ('%listCmd%') do (
    if !startCount! lss %maxProc% (
      set /a "startCount+=1, nextProc=startCount"
    ) else (
      call :wait
    )
    set cmd!nextProc!=%runCmd%
    echo -------------------------------------------------------------------------------
    echo !time! - proc!nextProc!: starting %runCmd%
    2>nul del %lock%!nextProc!
    %= Redirect the lock handle to the lock file. The CMD process will     =%
    %= maintain an exclusive lock on the lock file until the process ends. =%
    start /b "" cmd /c >"%lock%!nextProc!" 2^>^&1 %runCmd%
  )
  set "launch="

:wait
:: Wait for procs to finish in a loop
:: If still launching then return as soon as a proc ends
:: else wait for all procs to finish
  :: redirect stderr to null to suppress any error message if redirection
  :: within the loop fails.
  for /l %%N in (1 1 %startCount%) do 2>nul (
    %= Redirect an unused file handle to the lock file. If the process is    =%
    %= still running then redirection will fail and the IF body will not run =%
    if not defined endProc%%N if exist "%lock%%%N" 9>>"%lock%%%N" (
      %= Made it inside the IF body so the process must have finished =%
      echo ===============================================================================
      echo !time! - proc%%N: finished !cmd%%N!
      type "%lock%%%N"
      if defined launch (
        set nextProc=%%N
        exit /b
      )
      set /a "endCount+=1, endProc%%N=1"
    )
  )
  if %endCount% lss %startCount% (
    timeout /t 1 /nobreak >nul
    goto :wait
  )

2>nul del %lock%*
echo ===============================================================================

Upvotes: 14

loved.by.Jesus
loved.by.Jesus

Reputation: 2514

For people, like me, who land on this question searching for a Linux method to "batch" convert .svg pictures into .pdf

Create a mysvg2pdf.sh executable file in the directory where your pictures are with following code

#!/bin/bash
mkdir "$PWD"/pdf
for file in $PWD/*.svg
    do
        filename=$(basename "$file")
        inkscape "$file" --export-type=pdf --export-filename="$PWD"/pdf/"${filename%}.pdf"
    done

Execute it, ./mysvg2pdf.sh and a subfolder pdf is created with the corresponding .pdf converted files.

(Source: this answer)

Possible code adaptations

  • If you want to convert with inkscape into another format (as in the original question ;)) just change every appearance of the string pdf in the above code for your desired format, e.g., png.
  • If you have installed Inkscape via flatpak then substitute the command inkscape with the expression /usr/bin/flatpak run --branch=stable --arch=x86_64 --command=inkscape --file-forwarding org.inkscape.Inkscape (leave the rest unchanged, i.e., "$file" --export-type=...)
  • If you want to strip the original .svg extension of your files, so that the output file only has .pdf instead of .svg.pdf change the expression $(basename "$file") for $(basename "$file" | cut -d. -f1)
  • If you want to use another converter, for example the python converter cairosvg—which I heartily recommend, because it produces much smaller .pdf files–. Then change the whole inkscape command line inkscape "$file" ... "${filename%}.pdf" for a line with the cairosvg command: cairosvg "$file" -o "$PWD"/pdf/"${filename%}.pdf"

Upvotes: 4

Andreas
Andreas

Reputation: 728

Things have changed a bit for newer versions of Inkscape in Windows (v1.0 at the time writing). For command line, you can use inkscape.com instead of .exe. This will also work with portable versions. Moreover, the parameter --export-png has been replaced by --export-filename. So it should simply look like this:

FOR %%A IN (*.svg) DO "<path to Inkscape bin>\inkscape.com" %%A --export-filename=%%A.png
  • The export type should be detected automatically from the file extension. Otherwise you can explicitly specify it with --export-type=png.
  • For scaling you can use the parameter --export-dpi=DPI, or via width/height --export-width=WIDTH --export-height=HEIGHT

Upvotes: 1

Related Questions