Skip to content

Instantly share code, notes, and snippets.

@leifcr
Forked from Elrinth/InkscapeBatchConvert.bat
Last active May 14, 2024 11:28
Show Gist options
  • Save leifcr/80eb2a71a972fb3fc519474ca1c95b9a to your computer and use it in GitHub Desktop.
Save leifcr/80eb2a71a972fb3fc519474ca1c95b9a to your computer and use it in GitHub Desktop.
Batch converter for windows using inkscape and the command line

Batch convert svg|pdf|eps to eps|pdf|png|svg

Batch converter for windows using inkscape and the command line
Just download the file InkscapeBatchConvert.bat and put it in the folder you want to run it at. Then double click the file to start it.

Notes

The new PS1 script has more features and better support for scaling The batch script has slightly outdated functionality, so it's recommended to use the powershell script for conversions from SVG to other formats.

Troubleshooting

Check if your inkscape path is C:\Program Files\Inkscape\inkscape.exe, otherwise change the path in line 3 in the bat script

@Echo off
set "inkscapePath=C:\Program Files\Inkscape\inkscape.exe"
set /a count=0
set validInput1=svg
set validInput2=emf
set validInput3=wmf
set validOutput1=eps
set validOutput2=pdf
set validOutput3=png
set validOutput4=svg
echo.
echo This script allows you to convert all files in this folder from one file type to another.
echo (type q to quit at any question)
echo.
set valid=0
echo Allowed file types for source: %validInput1%, %validInput2%, %validInput3%
:whileInNotCorrect
set /p sourceType=What file type do you want to use as a source?
if "%sourceType%" EQU "%validInput1%" set valid=1
if "%sourceType%" EQU "%validInput2%" set valid=1
if "%sourceType%" EQU "%validInput3%" set valid=1
if "%sourceType%" EQU "q" exit /b
if %valid% EQU 0 (
echo Invalid input! Please use one of the following: %validInput1%, %validInput2%, %validInput3%
goto :whileInNotCorrect
)
echo.
set valid=0
echo Allowed file types for output: %validOutput1%, %validOutput2%, %validOutput3%, %validOutput4%
:whileOutNotCorrect
set /p outputType=What file type do you want to convert to?
if "%outputType%" EQU "%validOutput1%" set valid=1
if "%outputType%" EQU "%validOutput2%" set valid=1
if "%outputType%" EQU "%validOutput3%" set valid=1
if "%outputType%" EQU "%validOutput4%" set valid=1
if "%outputType%" EQU "q" exit /b
if %valid% EQU 0 (
echo Invalid input! Please use one of the following: %validOutput1%, %validOutput2%, %validOutput3%, %validOutput4%
goto :whileOutNotCorrect
)
if "%outputType%" EQU "%sourceType%" (
echo Input and Output are the same, no point in doing anything. Exiting...
exit /b
)
echo.
set toDelOrNot=n
if "%sourceType%" NEQ "pdf" (
if "%outputType%" EQU "%validOutput4%" (
set valid=0
:whilePdfDelNotCorrect
set /p toDelOrNot=EPS to SVG also generates pdfs, delete these after conversion? (y/n^)
if "%toDelOrNot%" EQU "y" set valid=1
if "%toDelOrNot%" EQU "n" set valid=1
if "%toDelOrNot%" EQU "q" exit /b
if %valid% EQU 0 (
echo Invalid input! Please type either y or n.
goto :whilePdfDelNotCorrect
)
)
)
:: 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 Conversion started. Will do %total% file(s).
echo.
set /a curNr=1
setlocal ENABLEDELAYEDEXPANSION
:: Running through all files found with the defined ending
for /R %%i in (.\*.%sourceType%) do (
set /a count=count+1
echo %%i -^> %%~pi%%~ni.%outputType% ^[!curNr!/%total%^]
:: we didn't select svg:
if "%outputType%" NEQ "%validOutput4%" (
"%inkscapePath%" --without-gui --file="%%i" --export-%outputType%="%%~pi%%~ni.%outputType%" --export-dpi=%dpi%
)
:: for svg export first pdf, then svg...
if "%outputType%" EQU "%validOutput4%" (
if "%sourceType%" NEQ "pdf" (
"%inkscapePath%" --without-gui --file="%%i" --export-pdf="%%~pi%%~ni.pdf" --export-dpi=%dpi%
)
"%inkscapePath%" --without-gui -z -f "%%i" -l "%%~pi%%~ni.%validOutput4%"
if "%toDelOrNot%" EQU "y" (
del "%%~pi%%~ni.pdf" /f /q
)
)
set /a curNr=curNr+1
)
echo.
echo %count% file(s) converted from %sourceType% to %outputType%!
echo.
pause
# Partially powershell version of the batch script
# This has multiple jobs that can convert in paralell
# Only tested between svg and png
# Read arguments from command line (sourceType, outputType, dpi, delete and width)
param(
[string]$source = "svg",
[string]$output = "png",
[int]$dpi = 96,
[int]$width = 0,
[int]$height = 1000,
[string]$inputFolder= '.',
[int]$exitAfterJobs = 1000
)
# Define your variables here
$validInputs = $("svg")
$validOutputs = "svg", "pdf", "eps", "png"
$inkscapePath = "C:\Program Files\inkscape\bin\inkscape.com"
function PrintUsage {
Write-Host "Usage: InkscapeBatchConvert.ps1 -source <sourceType> -output <outputType> -dpi <dpi> -width <width> -height <height> -inputFolder <inputFolder> -exitAfterJobs <exitAfterJobs>"
Write-Host "Example: InkscapeBatchConvert.ps1 -source svg -output png -dpi 96 -width 0 -height 1000 -inputFolder 'c:\myfolder' -exitAfterJobs 1000"
exit
}
# If both provided height and width is 0, exit, since that is an error
if ($width -eq 0 -and $height -eq 0) {
Write-Host "Both width and height cannot be 0. Please provide at least one of them."
exit
}
# Also exit if they are negative values
if ($width -lt 0 -or $height -lt 0) {
Write-Host "Width and height cannot be negative values."
exit
}
# Check if the input and output types are valid
if ($validInputs -notcontains $source) {
Write-Host "Invalid source type: $source. Valid source types are: $validInputs"
exit
}
if ($validOutputs -notcontains $output) {
Write-Host "Invalid output type: $output. Valid output types are: $validOutputs"
exit
}
# Read source
# Get all files with the source type
$files = Get-ChildItem $inputFolder -Recurse -Filter "*.$source"
Write-Host "Conversion started. Will do $($files.Count) file(s)."
# Initialize counter
$count = 0
# $q_height = 0
# $q_width = 0
# Maximum number of concurrent jobs
$maxJobs = 8
# Queue to hold the jobs
$jobQueue = [System.Collections.Queue]::new()
# Loop through all files
foreach ($file in $files) {
# Wait for a spot to open up
# If the number of jobs in the queue is equal to the maximum number of concurrent jobs
while ($jobQueue.Count -ge $maxJobs) {
# Wait for any job to complete
$completedJob = Get-Job | Wait-Job -Any
Write-Host "Job completed: $($completedJob.Id)"
# Get the results of the completed job if needed
Receive-Job -Job $completedJob
# Remove the completed job from the job list
Remove-Job -Job $completedJob
# Remove the completed job from the queue
$jobQueue = $jobQueue | Where-Object { $_.Id -ne $completedJob.Id }
}
$count++
if ($count -eq $exitAfterJobs) {
exit
}
$job = Start-Job -ScriptBlock {
param($file, $output, $dpi, $width, $height, $inkscapePath)
try {
$baseName = $file.Name.Replace($file.Extension, '')
Write-Host "$($file.FullName) -> $($file.DirectoryName)\$($baseName).$output [$count/$($files.Count)]"
# Query the height and width of the file, as we need to calculcate the aspect ratio
# Read the actual dimensions of the file (viewbox)
# Load the SVG file into an XML document
$xmlDoc = New-Object System.Xml.XmlDocument
$xmlDoc.Load($($file.FullName))
# Get the 'svg' element
$svgElement = $xmlDoc.DocumentElement
# Get the 'viewBox' attribute
$viewBox = $svgElement.GetAttribute("viewBox")
# if the viewbox is '', then exit
if ($viewBox -eq '') {
Write-Host "The file does not have a viewBox attribute. Exiting."
exit
}
# The viewBox attribute is a string of four numbers: min-x, min-y, width and height
$viewBoxValues = $viewBox -split ' '
# $q_minX = [double]$viewBoxValues[0]
# $q_minY = [double]$viewBoxValues[1]
$q_width = [double]$viewBoxValues[2]
$q_height = [double]$viewBoxValues[3]
Write-Host "Input Dimensions: Width: $q_width, Height: $q_height"
Write-Host "Output Dimensions: Width: $width, Height: $height"
# Delete the stupid output generated by querying the dimensions
# Calculate the correct width, if the width is 0
$calc_width = $width
$calc_height = $height
if ($width -eq 0) {
$calc_width = [Math]::Round($height * $q_width / $q_height)
}
# Calculate the correct height, if the height is 0
if ($height -eq 0) {
$calc_height = [Math]::Round($width * $q_height / $q_width)
}
Write-Host "Output dimensions Width: $calc_width, Height: $calc_height"
# Build the arguments
$arguments = @()
if ($output -eq "svg") {
$arguments += '-l '
}
$arguments += "-o", "`"$($file.DirectoryName)\$($baseName).$output`""
# Unless output is svg
if ($output -ne "svg") {
# Add dpi
$arguments += "--export-dpi=$dpi"
# Add width unless its 0
if ($calc_width -ne 0) {
$arguments += "--export-width=$calc_width"
}
# Add height unless its 0
if ($calc_height -ne 0) {
$arguments += "--export-height=$calc_height"
}
# $arguments += "--export-use-hints"
$arguments += "--export-area-page"
# $arguments += "--export-area-drawing"
}
$arguments += "`"$($file.FullName)`""
# Print out arguments
Write-Host "Arguments: $arguments"
Write-Host $inkscapePath $($arguments -join ' ')
# Write-Host $arguments
# Now run inkscape with the arguments
#
& $inkscapePath $arguments
# Define the done and output folders
$doneFolder = Join-Path $file.DirectoryName 'done'
$outputFolder = Join-Path $file.DirectoryName 'output'
# Create the folders if they don't exist
if (!(Test-Path -Path $doneFolder)) {
New-Item -ItemType Directory -Path $doneFolder | Out-Null
}
if (!(Test-Path -Path $outputFolder)) {
New-Item -ItemType Directory -Path $outputFolder | Out-Null
}
# Move the SVG file to the done folder
Move-Item -Path $file.FullName -Destination $doneFolder
# Move the PNG file to the output folder
$pngFile = Join-Path $file.DirectoryName "$($baseName).$output"
Move-Item -Path $pngFile -Destination $outputFolder
}
catch {
Write-Host "Error: $($_.Exception.Message)"
}
} -ArgumentList $file, $output, $dpi, $width, $height, $inkscapePath
# Add the job to the queue
$jobQueue += $job
}
Write-Host
Write-Host "$count file(s) converted from $source to $output!"
Write-Host
# Wait for all remaining jobs to complete
foreach ($job in Get-Job) {
$job | Wait-Job | Receive-Job
$job | Remove-Job
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment