Skip to content

Commit ae1cd75

Browse files
author
Jonas Kamsker
committed
Add convert-images2webp.ps1 script and documentation for image conversion to WebP format
1 parent af3fffb commit ae1cd75

File tree

3 files changed

+234
-0
lines changed

3 files changed

+234
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ Mega Collection of PowerShell Scripts
230230
| Script | Description |
231231
| ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- |
232232
| [convert-csv2txt.ps1](scripts/convert-csv2txt.ps1) | Converts a .CSV file to a text file. [Read more »](docs/convert-csv2txt.md) |
233+
| [convert-images2webp.ps1](scripts/convert-images2webp.ps1) | Converts images in a directory or a single image file to WebP format in parallel. [More »](docs/convert-images2webp.md) |
233234
| [convert-mysql2csv.ps1](scripts/convert-mysql2csv.ps1) | Converts a MySQL database table to a .CSV file. [More »](docs/convert-mysql2csv.md) |
234235
| [convert-ps2bat.ps1](scripts/convert-ps2bat.ps1) | Converts a PowerShell script to a Batch script. [More »](docs/convert-ps2bat.md) |
235236
| [convert-ps2md.ps1](scripts/convert-ps2md.ps1) | Converts the comment-based help of a PowerShell script to Markdown. [More »](docs/convert-ps2md.md) |

docs/convert-images2webp.md

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# convert-images.ps1
2+
3+
This PowerShell script converts images in a directory or a single image file to WebP format in parallel.
4+
5+
## Parameters
6+
7+
| Parameter | Description |
8+
| --- | --- |
9+
| `-InputPath` | The path to the input directory containing images or a single image file. |
10+
| `-OutputDir` | The path to the directory where the converted WebP files will be saved. It will be created if it doesn't exist. |
11+
| `-Quality` | The quality setting for the WebP conversion (0-100). Lower values mean smaller files but potentially lower quality. Defaults to 50. |
12+
| `-Lossless` | Specifies whether to use lossless WebP compression ($true) or lossy compression ($false). Defaults to $true. |
13+
| `-MaxParallel` | The maximum number of image conversions to run concurrently. Defaults to 10. |
14+
15+
## Description
16+
17+
The script takes advantage of PowerShell's parallel processing capabilities to efficiently convert multiple image files. It supports various input formats including:
18+
- jpg/jpeg
19+
- png
20+
- gif
21+
- bmp
22+
- tiff
23+
24+
The converted files are saved in WebP format, which often provides superior compression while maintaining quality.
25+
26+
## Examples
27+
28+
```powershell
29+
# Convert all images in a directory
30+
./convert-images.ps1 -InputPath .\covers -OutputDir .\covers-webp -Quality 50 -Lossless $true -MaxParallel 10
31+
32+
# Convert a single image
33+
./convert-images.ps1 -InputPath .\my_image.png -OutputDir .\output -Quality 80 -Lossless $false
34+
```
35+
36+
## Requirements
37+
38+
- PowerShell 7.0 or higher (required for ForEach-Object -Parallel)
39+
- ImageMagick must be installed and accessible via the 'magick' command in your PATH

scripts/convert-images2webp.ps1

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#Requires -Version 7.0
2+
3+
<#
4+
.SYNOPSIS
5+
Converts images in a directory or a single image file to WebP format in parallel.
6+
7+
.DESCRIPTION
8+
This script takes an input directory containing images (jpg, jpeg, png, gif, bmp, tiff) or a single image file,
9+
and converts them to the WebP format using ImageMagick's 'magick' command.
10+
The conversion process runs in parallel to speed up processing large numbers of files.
11+
The level of parallelism can be controlled.
12+
13+
.PARAMETER InputPath
14+
The path to the input directory containing images or a single image file.
15+
16+
.PARAMETER OutputDir
17+
The path to the directory where the converted WebP files will be saved. It will be created if it doesn't exist.
18+
19+
.PARAMETER Quality
20+
The quality setting for the WebP conversion (0-100). Lower values mean smaller files but potentially lower quality. Defaults to 50.
21+
22+
.PARAMETER Lossless
23+
Specifies whether to use lossless WebP compression ($true) or lossy compression ($false). Defaults to $true.
24+
25+
.PARAMETER MaxParallel
26+
The maximum number of image conversions to run concurrently. Defaults to 10.
27+
28+
.EXAMPLE
29+
.\convert_parallel.ps1 -InputPath .\covers -OutputDir .\covers-webp -Quality 50 -Lossless $true -MaxParallel 10
30+
Converts all supported images in the '.\covers' directory to WebP in '.\covers-webp' using quality 50, lossless compression, running up to 10 conversions simultaneously.
31+
32+
.EXAMPLE
33+
.\convert_parallel.ps1 -InputPath .\my_image.png -OutputDir .\output -Quality 80 -Lossless $false
34+
Converts the single file '.\my_image.png' to WebP in '.\output' using quality 80 and lossy compression. Parallelism doesn't apply to single files.
35+
36+
.NOTES
37+
Requires PowerShell 7.0 or higher for ForEach-Object -Parallel.
38+
Requires ImageMagick to be installed and accessible via the 'magick' command in your PATH.
39+
Progress reporting for parallel operations is limited; output messages might appear interleaved.
40+
#>
41+
param (
42+
[Parameter(Mandatory=$true)]
43+
[string]$InputPath,
44+
45+
[Parameter(Mandatory=$true)]
46+
[string]$OutputDir,
47+
48+
[ValidateRange(0,100)]
49+
[int]$Quality = 50,
50+
51+
[bool]$Lossless = $true,
52+
53+
[ValidateRange(1, [int]::MaxValue)] # Ensure at least 1 parallel task
54+
[int]$MaxParallel = 10
55+
)
56+
57+
# --- Input Validation and Setup ---
58+
59+
# Check if input exists
60+
if (-not (Test-Path $InputPath)) {
61+
Write-Error "Input path does not exist: $InputPath"
62+
exit 1
63+
}
64+
65+
# Create output directory if it doesn't exist
66+
if (-not (Test-Path $OutputDir -PathType Container)) {
67+
Write-Host "Creating output directory: $OutputDir"
68+
try {
69+
New-Item -ItemType Directory -Path $OutputDir -ErrorAction Stop | Out-Null
70+
} catch {
71+
Write-Error "Failed to create output directory '$OutputDir': $_"
72+
exit 1
73+
}
74+
}
75+
76+
# Check if ImageMagick is installed and accessible
77+
if (-not (Get-Command magick -ErrorAction SilentlyContinue)) {
78+
Write-Error "ImageMagick is not installed or not in your PATH. Please install it from https://imagemagick.org/."
79+
exit 1
80+
}
81+
82+
# Check if input is a file or directory
83+
$InputItem = Get-Item $InputPath
84+
$isFileInput = $InputItem -is [System.IO.FileInfo]
85+
86+
# Convert lossless parameter to string for command
87+
$losslessValue = $Lossless.ToString().ToLower()
88+
89+
Write-Host "Starting conversion..."
90+
Write-Host "Input: $InputPath"
91+
Write-Host "Output: $OutputDir"
92+
Write-Host "Quality: $Quality"
93+
Write-Host "Lossless: $Lossless"
94+
if (!$isFileInput) {
95+
Write-Host "Max Parallelism: $MaxParallel"
96+
}
97+
Write-Host "-------------------------------------"
98+
99+
# --- Conversion Functions ---
100+
101+
# Function to convert a single file (used for non-parallel case)
102+
function Convert-SingleFile {
103+
param (
104+
[string]$FilePath,
105+
[string]$OutDir,
106+
[int]$ConvQuality,
107+
[string]$ConvLosslessValue
108+
)
109+
110+
$fileName = [System.IO.Path]::GetFileName($FilePath)
111+
$fileNameWithoutExt = [System.IO.Path]::GetFileNameWithoutExtension($FilePath)
112+
$outputFilePath = Join-Path $OutDir "$fileNameWithoutExt.webp"
113+
114+
Write-Host "Converting '$fileName' to WebP..."
115+
try {
116+
# Use Start-Process to capture stderr better if needed, or stick with '&' for simplicity
117+
& magick $FilePath -quality $ConvQuality -define webp:lossless=$ConvLosslessValue $outputFilePath
118+
Write-Host "Successfully converted '$fileName' to '$outputFilePath'" -ForegroundColor Green
119+
}
120+
catch {
121+
Write-Error "Failed to convert '$fileName': $_"
122+
# Consider adding specific error details from stderr if using Start-Process
123+
}
124+
}
125+
126+
# --- Main Conversion Logic ---
127+
128+
$startTime = Get-Date
129+
130+
if ($isFileInput) {
131+
# Process single file directly
132+
Convert-SingleFile -FilePath $InputPath -OutDir $OutputDir -ConvQuality $Quality -ConvLosslessValue $losslessValue
133+
$totalFiles = 1
134+
}
135+
else {
136+
# Process all image files in directory using parallel processing
137+
Write-Host "Gathering image files from '$InputPath'..."
138+
$imageFiles = Get-ChildItem -Path $InputPath -File | Where-Object {
139+
$_.Extension -match '\.(jpg|jpeg|png|gif|bmp|tiff)$'
140+
}
141+
142+
$totalFiles = $imageFiles.Count
143+
$processedCount = 0 # Simple counter, not perfectly synced for progress bar
144+
145+
if ($totalFiles -eq 0) {
146+
Write-Warning "No supported image files found in '$InputPath'."
147+
exit 0
148+
}
149+
150+
Write-Host "Found $totalFiles image files. Starting parallel conversion (MaxParallel = $MaxParallel)..."
151+
152+
$imageFiles | ForEach-Object -Parallel {
153+
# Variables from the outer scope need $using:
154+
$currentFile = $_
155+
$fName = $currentFile.Name
156+
$fNameWithoutExt = $currentFile.BaseName
157+
$outputFPath = Join-Path $using:OutputDir "$fNameWithoutExt.webp"
158+
159+
Write-Host "($PID) Starting conversion: $fName" # ($PID) shows the process ID handling this item
160+
161+
try {
162+
# Execute ImageMagick command
163+
& magick $currentFile.FullName -quality $using:Quality -define webp:lossless=$using:losslessValue $outputFPath
164+
165+
# Basic success message (output might be interleaved)
166+
Write-Host "($PID) Finished conversion: $fName -> $outputFPath" -ForegroundColor Cyan
167+
}
168+
catch {
169+
# Basic error message (output might be interleaved)
170+
Write-Error "($PID) Failed to convert '$fName': $_"
171+
}
172+
173+
# Incrementing a counter for precise progress in parallel is complex.
174+
# This provides a basic idea but isn't a reliable progress bar.
175+
# [System.Threading.Interlocked]::Increment([ref]$using:processedCount) | Out-Null
176+
# $prog = [math]::Round(($using:processedCount / $using:totalFiles) * 100)
177+
# Write-Progress -Activity "Converting images to WebP (Parallel)" -Status "Processed approx. $using:processedCount of $using:totalFiles" -PercentComplete $prog -Id 1
178+
179+
} -ThrottleLimit $MaxParallel # Control the number of parallel runs
180+
181+
# Write-Progress -Activity "Converting images to WebP (Parallel)" -Completed -Id 1
182+
Write-Host "-------------------------------------"
183+
Write-Host "Parallel conversion process finished."
184+
}
185+
186+
$endTime = Get-Date
187+
$duration = $endTime - $startTime
188+
189+
Write-Host "====================================="
190+
Write-Host "Conversion Summary"
191+
Write-Host "Total files processed: $totalFiles"
192+
Write-Host "Duration: $($duration.ToString())"
193+
Write-Host "Output directory: $OutputDir"
194+
Write-Host "=====================================" -ForegroundColor Green

0 commit comments

Comments
 (0)