Optimize JPG images for internet using jpegtran and PowerShell

Reduce size of existing JPG images without loosing quality with jpegtran

Recently I wrote an article about optimizing PNG images for intenrent using pngcrush and PowerShell. I actually used this method to optimize all PNG images on my website.

Although I mostly use PNG images, there are still some JPEG images I use on the pages and this was not included in optimization with PNGCRUSH utility since it is specialized for PNG. I saw the potential of using the same PowerShell script for JPEG image optimization, I just needed a utility which will do the heavy lifting of lossless compression on the JPEG images.

I decided to use JPEGTRAN which comes as a part of IJG toolkit. You can download binaries from this link or you can download it along with PowerShell script from download section of this article page.

Syntax of jpegtran tool is pretty simple and you can always get all options by running help command with jpegtran /? in command prompt.

In order to reduce image file size you need to run it with -optimize and -copy none arguments. Example call would be

C:\jpg9cexe>jpegtran -optimize -copy none input_file_path.jpg output_file_path.jpg

The jpegtran tool will not generate any output message after file optimization, so one more reason why I wrapped it with PowerShell. Otherwise, I would not have a status of the optimization process.

Also the PowerShell script will iterate though all files including sub-folders and pass them to jpegtran for optimization. If the image size does not change or for some reason it is greater than the input image file, there will be no changes applied to the file.

Note

Update the path to jpegtran utility to the actual location on your machine.
Make sure you backup your images folder before running the following PowerShell script to avoid any data loss.

Param(    
[Parameter(Mandatory=$true)]    
[string]$folder  
 )    
  
$libPath = $PSScriptRoot + "\lib\pngcrush\pngcrush_1_8_11_w64.exe"
  
$files = get-childitem $folder -recurse -force -include *.png 
foreach($inputFile in $files){   

   #Temp file path
   $outputFilePath = $inputFile.FullName + ".crushed"

   #Call pngcrush
   $args = $inputFile.FullName + " " + $outputFilePath
   Start-Process -FilePath $libPath -ArgumentList $args -Wait

   $originalFileSize = (Get-Item $inputFile.FullName).length
   $optimizedFileSize = (Get-Item $outputFilePath).length

   if($optimizedFileSize -lt $originalFileSize){
        #Compression reduced file size
        Remove-Item $inputFile.FullName -Force
        Rename-Item $outputFilePath -NewName $inputFile.Name

        #Prepare output
        $savedBytes = $originalFileSize - $optimizedFileSize
        $savedPercentage = [math]::Round(100-($optimizedFileSize / $originalFileSize)*100)
        $message = $inputFile.FullName + " " + $savedBytes + "bytes " + $savedPercentage + "%"

        Write-Output $message
   }
   else{
        #Compression did not reduced file size
        Remove-Item $outputFilePath -Force
   }
}  
    

The output from the PowerShell command run will come with file path, saved bytes and percentage of reduced file size

D:\Gitlab\powershell-scripts>powershell.exe -file Optimize-Jpg.ps1 -folder D:\Gitlab\powershell-scripts\jpegtran 
D:\Gitlab\powershell-scripts\jpegtran\sample.jpg 4288bytes 16% 

D:\Gitlab\powershell-scripts>

References

Disclaimer

Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.


About the author

DEJAN STOJANOVIC

Dejan Stojanovic is a passionate Software Architect/Developer. He is highly experienced in .NET programming platform includion ASP.NET MVC and WebApi. He likes working on new technologies and exciting challenging projects

CONNECT WITH DEJAN Loginlinkedin Logintwitter Logingoogleplus Logingoogleplus

.NET

read more

JavaScript

read more

SQL/T-SQL

read more

Umbraco CMS

read more

Comments for this article