Powershell Image Conversion script – Part 1: Image conversion



In one of my former jobs I was responsible for a few servers that where used for an OCR (Optical Character Processing) proces. All the dossiers that were ever archived were being scanned and processed to range of  TIFF files of the individual pages into a directory.

Internally dossiers were viewable through a portal that searched for the files in a certain directory.

The proces was implemented with batch files calling IrfanView that processed the pages of the dossiers to images that would be viewable in a browser. The TIFF files were converted to GIF because viewing TIFF files is not a standard feature in browser.

After Irfanview processed the images  another batch file would be executed to copy the files to there final destination and archive the original files.

The problem

During the day the IrfanView proces would crash multiple times (read about 20 times a day). Further of all the program IrfanView is/was only free for personal use only. The company didn’t have a license so the product had to be replaced.

During he crash all the images that were waiting to be processed got lost and had to be copied from an archive to the processing directory. You can imagine that wasn’t a good situation where 80% of the company relied on the documents to be available on the portal.

All the  batch file were configured using the Task scheduler of Windows Server 2003. They were configured to run at a certain moment after each other. If one of the batch processes was unable to finish in time the other batch proces would cut in and to his work.

That again is not a reliable situation for the company.

All the dossiers were saved in a single directory. The company had more than 2,5 million dossiers. Anyone who ever had a lot of files in one directory knows that filesystems will have trouble scanning a directory that contains thousands of directories (at least Windows based filesystems). The directory already contained over 20.000 dossiers so performance was starting to be a problem.

Another problem that created an unreliable situation.

The challenge

The following obstacles had to be overcome to create a reliable situation:

  • create a solution where third party software wasn’t needed anymore like IrfanView
  • create a script to convert the images from any imagetype to another imagetype
  • make functionality
    • that would group individual directories.
    • that check all the files and directories for possible errors
    • that would read a config file or create one
  • logging the script actions had to be possible
  • the solution had to do the whole proces in one go

Hmm a lot of work. In the series I will show how to do this and the source files will be downloadable.

The series exist of the following:

  1. Create functionality for image conversion
  2. Create functionality for logging
  3. Create functionality for configuration files
  4. Finalizing and implement check functionality

Part 1 will be explained in this article. The rest will be posted soon.

Part 1: Create functionality for image conversion

I gave myself the following demands what the script had to be or image conversion:

  1. The script had convert had to search for specific image type
  2. The script had to convert any imagetype to any other image type
  3. The script had to be able to resize the image
  4. The name of the new image has to be unique in the dossierfolder.

The general idea of he conversion is to call the method for the conversion twice for every image. One for the large image and once for the thumbnail. This way we dont have to create two seperate functions.

The top part of the script looks as follows:


In the first part of this article we won’t need all the parameters. The reason I included them is because in the following articles they’ll be needed.

Below the parameters we’re adding .Net functionality to the powershell script to be able to convert the images.

The first part of the function contains the following code:


# Function Convert-Image
# This function converts the image and creates a thumbnail
# Parameters:
# [string] $sourceImage : Path to image
# [string] $destinationDir : Destination directory
# [int] $newSize : New size for image
# [string] $extension : New extension or image
# [string] $imgFormat : New imageformat for image
Function Convert-Image

The function has 5 parameters:

  1. sourceImage: Contains the full path to the original directory
  2. destinationDir: Path to the destination of the newly created image
  3. newSize: The size of the longest side of the new image
  4. extension: Extension of the new image
  5. imgFormat: The format of the new image

The next step is to load the source image and get several data rom it like width and height etc.

# Create a new imageobject
$oldImage = new-object System.Drawing.Bitmap $sourceImage

# Get the height of the original image
$longSide = $oldImage.Height

# If the height is smaller than width
If($oldImage.Height -lt $oldImage.Width)
# Set the longest side to be the width
$longSide = $oldImage.Width

In the code above the image is read into memory. Than the scripts looks for the longest side of the image.
Later in the script were using this value to resize the image.

Next up is to decide what the new width and height are going to be.

# If the longest side is greater than the new size
If ($longSide -gt $newSize)
# If the height of the original image is lower than the with
If ($oldImage.Height -lt $oldImage.Width)
# Set the variables
$newH = $newSize
$newW = [int]($oldImage.Width * $newSize / $oldImage.Height)

# If the height of the original image is greater than the width
$newW = $newSize
$newH = [int]($oldImage.Height * $newW / $oldImage.Width)

The script first checks if the longest side is greater than the new size of the image. If this isn’t the case there is no need for it to be resized. You could resize the image from a smaller version to a larger image but than the quality of the image would be insufficient to work with.

The next thing the script checks is if the original image’s height is smaller than the width. Based on this the new height en new width are calculated.

The next code creates a new image object in memory. Than chooses the algorithm is wants to use to convert the image.
Finally it creates the new image with the desired size.

# Create a new imageobject
$newImage = new-object System.Drawing.Bitmap $newW, $newH
$g = [System.Drawing.Graphics]::FromImage($newImage)

# Use high quality conversion
$g.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic

# Resize the image
$g.DrawImage($oldImage, 0, 0, $newW, $newH)

The next code creates the new directory for the image and checks if it is successfully created.

# Create the folders where the image will be copied
$oldFolder = [System.IO.Path]::GetDirectoryName($sourceImage)
$newFolder = Replace-String $source $destinationDir $oldFolder

# Check if the path exists. If not create it
If(!(Test-Path $newFolder))
New-Item $newFolder -type directory

The code above uses a function named “Replace-String”. I created this function to easily create a new directory based on the old directory. The code for the function is as follows:

# Function Replace-String
# This function replaces a certain text in a string
# Parameters:
# [string] $find: Text that needs to be searched for
# [string] $replace: Original text needs to be replaced with
# [string] $string: Text what should be searched in
Function Replace-String([string]$find, [string]$replace, [string]$string)
# Replace text
$x = $string.Replace($find, $replace)

# Return results
return $x

I could have used the Replace function but I wanted to make a nice method from it.

The next code will set up the new path to the new image and write the data rom memory to it.
Further it will dispose the used data from memory

# Setup the full path of the new image
$newFile = $newFolder + "\" + $name

# Save the new image
$newImage.Save($newFile, ([system.drawing.imaging.imageformat]::$imageFormat))

# Remove data of the proces from memory

Finally the function ends with the code below:

Write-host -NoNewLine "."

How to execute the created code:

Convert-Image C:\Imagedir\12423423\image1.jpg C:\Portal\124\124234\ 200 .jpg jpeg

Leave a Reply

Your email address will not be published.