Skip to main content

How to Convert Image Formats (PNG, JPG, BMP) in Batch Script

Batch scripts frequently manage file systems filled with graphics, but they lack the built-in capability to manipulate image encoding natively. Converting a heavy BMP to a compact JPG, or changing a JPG to a lossless PNG, requires interacting with external utilities or native .NET Framework libraries via PowerShell.

In this guide, we will demonstrate how to perform format conversions seamlessly using a PowerShell bridge.

The Strategy: The System.Drawing Namespace

Windows includes the .NET System.Drawing library natively on all Windows 10 and 11 systems. By invoking this library from PowerShell inside our Batch script, we can load an image into memory and save it out in a completely different format, without installing any third-party tools.

Native Windows Capability

This method uses libraries included with every modern Windows installation. No downloads, no installers, and no external dependencies are required. This works on all Windows 10 1809+ and Windows 11 systems.

Implementation Script

@echo off
setlocal enabledelayedexpansion

:: 1. Define Paths
set "IMAGE_IN=C:\Temp\photo.bmp"
set "IMAGE_OUT=C:\Temp\photo_converted.jpg"
set "TARGET_FORMAT=Jpeg"

:: Check if source exists
if not exist "!IMAGE_IN!" (
echo [ERROR] Source image "!IMAGE_IN!" not found.
pause
exit /b 1
)

echo Converting "!IMAGE_IN!" to !TARGET_FORMAT!...

:: 2. Execute via PowerShell Bridge
powershell -NoProfile -Command ^
"Add-Type -AssemblyName System.Drawing; " ^
"$img = [System.Drawing.Image]::FromFile('!IMAGE_IN!'); " ^
"$img.Save('!IMAGE_OUT!', [System.Drawing.Imaging.ImageFormat]::!TARGET_FORMAT!); " ^
"$img.Dispose();"

:: 3. Verify Success
if !errorlevel! EQU 0 (
echo.
echo ==========================================
echo CONVERSION SUCCESSFUL!
echo Output saved to: !IMAGE_OUT!
echo ==========================================
) else (
echo [ERROR] Conversion failed with exit code: !errorlevel!
echo The source file may be corrupt, locked, or an unsupported format.
)

pause
Always Call Dispose()

The $img.Dispose(); command is critical. If omitted, the source file remains locked in memory until the PowerShell session ends. This can cause "file in use" errors if you attempt to move, rename, or delete the source file immediately after conversion.

Supported Output Formats

In the script above, you can change TARGET_FORMAT to any standard .NET image format name:

FormatExtensionNotes
Jpeg.jpgLossy compressed, best for photos
Png.pngLossless, supports transparency
Bmp.bmpUncompressed, maximum quality
Gif.gif256 colors, suitable for simple graphics
Tiff.tiffLossless, used in printing and scanning

Bulk Converting an Entire Directory

To convert every PNG in a folder to JPG, wrap the conversion logic in a FOR loop:

@echo off
setlocal enabledelayedexpansion

set "SOURCE_DIR=C:\Photos\Raw"
set "DEST_DIR=C:\Photos\Web"
set "TARGET_FORMAT=Jpeg"

:: Validate source directory
if not exist "!SOURCE_DIR!\" (
echo [ERROR] Source directory not found: !SOURCE_DIR!
pause
exit /b 1
)

:: Create destination directory if missing
if not exist "!DEST_DIR!" mkdir "!DEST_DIR!"

echo Starting bulk conversion...
echo.

set "successCount=0"
set "failCount=0"

for %%F in ("!SOURCE_DIR!\*.png") do (
echo Converting: %%~nxF

set "outFile=!DEST_DIR!\%%~nF.jpg"

powershell -NoProfile -Command ^
"Add-Type -AssemblyName System.Drawing; " ^
"$img = [System.Drawing.Image]::FromFile('%%F'); " ^
"$img.Save('!outFile!', [System.Drawing.Imaging.ImageFormat]::!TARGET_FORMAT!); " ^
"$img.Dispose();"

if !errorlevel! EQU 0 (
set /a "successCount+=1"
) else (
echo [FAILED] %%~nxF
set /a "failCount+=1"
)
)

echo.
echo ==========================================
echo Conversion complete.
echo Succeeded: !successCount!
echo Failed: !failCount!
echo Output: !DEST_DIR!
echo ==========================================
pause
Delayed Expansion Required

The bulk conversion script uses !outFile! inside the for loop. This requires enabledelayedexpansion which is declared at the top of the script. Without delayed expansion, %outFile% would always evaluate to the same value for every iteration.

Why Convert Images via Script?

  1. Web Optimization: A script that automatically detects uncompressed .bmp files in a web directory and converts them to .jpg for faster page loading.
  2. Archiving: Reducing the storage footprint of daily screenshot logs by converting them to heavily compressed formats.
  3. Standardization: Normalizing all incoming user uploads to a single format before processing.

Important Considerations

JPEG Compression Quality

The simple .Save() method uses the default JPEG compression ratio (usually 75%). For exact control over JPEG quality levels, a more complex PowerShell script defining EncoderParameters is required:

$encoder = [System.Drawing.Imaging.Encoder]::Quality
$params = New-Object System.Drawing.Imaging.EncoderParameters(1)
$params.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter($encoder, 90)
$codec = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | Where-Object { $_.FormatID -eq [System.Drawing.Imaging.ImageFormat]::Jpeg.Guid }
$img.Save('output.jpg', $codec, $params)
ImageMagick Alternative

If you need to perform heavy graphics work (resizing, cropping, adding text, watermarking), the ImageMagick CLI tool is faster and more robust than the .NET bridge:

magick convert "input.png" -quality 90 "output.jpg"

ImageMagick is a third-party download but is the industry standard for command-line image processing.

Special Characters in Filenames

The .FromFile() method handles spaces in filenames correctly, but files containing single quotes ' in their names will break the PowerShell command. For maximum robustness with arbitrary filenames, pass the paths as arguments to PowerShell instead of embedding them in the command string.

Conclusion

Converting image formats is a high-value file management task that simplifies storage and web distribution. By leaning on the native .NET capabilities exposed through PowerShell, you can orchestrate single or bulk graphic conversions directly from your Batch workflow. This approach guarantees zero reliance on third-party downloads while delivering professional-grade image processing.