Manipulating Many Images at Once Using Photoshop, GIMP, ImageMagick, PIL and OpenCV: GIMP (Part 3 of 6)

This is part 3 of 6 of a mini-series of posts that discuss how to manipulate many images at once (instead of individually) using a variety of techniques. Please refer to part 1 of 6 for more information.

This post explores how to batch process images in GIMP (GNU Image Manipulation Program). We will resize and apply the sepia tone effect to a group of photos. For resizing, each image is scaled to three (3) different sizes, 75%, 50%, 25%, of the original. The sepia tone effect is achieved with image desaturation and blending using the algorithm discussed in the introductory post.

All code on this page was developed with & tested against GIMP 2.8.16.

Batch Processing in GIMP

Batch processing in GIMP can be accomplished by:

  • BIMP (Batch Image Manipulation Plugin). There are some versions of GIMP with this plugin pre-installed, otherwise it has to be downloaded and installed manually
  • Extending GIMP functionality by creating a GIMP plug-in with Script-Fu or Python

A simple set of tasks (like resizing images, adding watermarks) can be easily performed on multiple images using only BIMP. However, complex tasks require scripting.

For resizing, we will create a plug-in with Python scripting. The plug-in will be responsible for accepting an input directory of images, scaling the each input image to 75%, 50% and 25% and saving the results to a specified output directory.

We use a combination of both BIMP and Python scripting for the sepia tone effect. We create a plug-in with Python scripting which accepts one image and applies the sepia tone effect to it. BIMP runs the plug-in on multiple input images and saves the results.

Resizing Images

We will resize images based on size percentage of the original image and not only that, but we will create three different sizes (75%, 50%, 25%) as well.

There are a few ways to approach this:

  • Run BIMP, select Resize and specify Set to a percentage of the original. Repeat for each of the three (3) sizes
  • Write a plug-in that takes an input directory of images and then creates & saves the resized images to (preferably) a different directory

We will go with the latter option.

Old Car ResizingOriginal Image Scaled to 75%, 50% and 25%

Resizing One Image to Several Sizes

The following Python code snippet scales the current image into three (3) different sizes, 75%, 50% & 25%, and saves them into the output directory. The register portion allows the function to be accessible through the GIMP Filters menu as a plug-in. This can be tested on one image by saving the full script to a file in GIMP’s plug-ins directory and executing the script through Filters -> MDT -> Create Scaled Versions, which will run it on the current image. The plug-in prompts for the output directory.

# *****
# create_scaled_versions
#
# Description: Resize current image to 25%, 50% and 75% of original
#
# Parameters:
# 		inGimpImg : Current image
#		inLayerinGimpImg : Current layer in current image (not used)
#		inOutputDir : Directory to save resized images
# *****
def create_scaled_versions(inGimpImg, inLayerinGimpImg, inOutputDir):
	resizePercentageArray = [75, 50, 25]  # Percentages to scale input image
 
	gimpImgRFN = get_root_name_from_filepath(inGimpImg.filename) 
 
	for resizePercentage in resizePercentageArray:
		scaledHeight = int(inGimpImg.height * resizePercentage / 100)
		scaledWidth = int(inGimpImg.width * resizePercentage / 100)
		outputImgFN = os.path.join(inOutputDir, gimpImgRFN) + "_" + str(resizePercentage) + "percent.jpg"
		scale_and_save_image(inGimpImg, scaledWidth, scaledHeight, outputImgFN)
 
 
# *****
# scale_and_save_image
#
# Description: Scales and input image and saves the result
#
# Parameters:
# 		inImg : Image to be resized
#		inWidth : Resize width
#		inHeight : Resize height
#		inFilePathName : Path and filename to save resized image
# *****
def scale_and_save_image(inImg, inWidth, inHeight, inFilePathName):
 
	# Duplicate the image & resize
	scaledImg = pdb.gimp_channel_ops_duplicate(inImg)  # use currently loaded image
	pdb.gimp_image_scale(scaledImg, inWidth, inHeight)
 
	# Save the resized image as a jpg
	flattenedImgLayer = pdb.gimp_image_flatten(scaledImg)
	pdb.file_jpeg_save(scaledImg, flattenedImgLayer, inFilePathName, inFilePathName, 0.9, 0, 0, 0, "Created with GIMP", 0, 0, 0, 0)	
 
 
register(
	"create_scaled_versions",
	"Create Scaled Versions",
	"Creates different scaled versions of an image",
	"ytirahc",
	"Proprietary",
	"2016",
	"/Filters/MDT/Create Scaled Versions",
	"*",
	[
		(PF_DIRNAME, "outputFolder", "Output directory", "")
	],
	[],
	create_scaled_versions)

Resizing Multiple Images to Several Sizes

To resize multiple images at once, we include a function to find & process all jpg image files in the input directory as illustrated in the code snippet below. The register portion allows the function to be accessible through the GIMP Filters menu as a plug-in. This can be tested on a directory of input images by saving the full script to a file in GIMP’s plug-ins directory and executing the script through Filters -> MDT -> Create Scaled Versions in Batch. The plug-in prompts for the both the input and output directories.

# *****
# create_scaled_versions_batch
#
# Description: Processes a directory of images to resize and save the results
#
# Parameters:
# 		inGimpImg : Current image (not used)
#		inLayerinGimpImg : Current layer in current image (not used)
#		inInputDir : Directory with images to be resized
#		inOutputDir : Directory to save resized images
# *****
def create_scaled_versions_batch(inGimpImg, inLayerinGimpImg, inInputDir, inOutputDir):
 
	for fileInDir in os.listdir(inInputDir):   # Look at all files in the input directory
 
		try:
 
			inputImgFN = os.path.join(inInputDir, fileInDir)
 
			# Process only images that are jpgs
			inputImage = None
			if(inputImgFN.lower().endswith(('.jpeg', '.jpg'))):
				inputImage = pdb.file_jpeg_load(inputImgFN, inputImgFN)
 
			# Scale and save jpgs images
			if(inputImage != None):
				if(len(inputImage.layers) > 0):
					create_scaled_versions(inputImage, inputImage.layers[0], inOutputDir)
 
		except Exception as err:
			gimp.message("Unexpected error: " + str(err))
 
register(
	"create_scaled_versions_batch",
	"Create Scaled Versions in Batch",
	"Creates different scaled versions of images in a directory",
	"ytirahc",
	"Proprietary",
	"2016",
	"/Filters/MDT/Create Scaled Versions in Batch",
	"*",
	[
		(PF_DIRNAME, "inputFolder", "Input directory", ""),
		(PF_DIRNAME, "outputFolder", "Output directory", "")
	],
	[],
	create_scaled_versions_batch)

Applying the Sepia Tone Effect

Applying the sepia tone effect to an image will give it an old, antique-ish photograph look. As a recap of the discussion of what the sepia tone effect algorithm entails, here is a list of steps to achieve it:

  1. Desaturate the image. The resulting image is greyscale.
  2. Apply a mild gaussian blur since most old photos are slightly blurry.
  3. Add a reddish brown (or dark orange) solid color layer above the photo layer, using the soft light blend mode.

Old Car Sepia Tone EffectSepia Tone Effect Applied to Original Image

For more information regarding the sepia tone effect algorithm, please refer to the introductory post.

Applying the Sepia Tone Effect to One Image

The following Python code snippet applies the sepia tone effect to the current image. The register portion allows the function to be accessible through the GIMP Filters menu as a plug-in. This can be tested on the current image by saving the full script to a file in GIMP’s plug-ins directory and executing the script through Filters -> MDT -> Create Sepia Effect.

# *****
# create_sepia_effect
#
# Description: Applies sepia tone effect to current image
#
# Parameters:
# 		inGimpImg : Current image
#		inLayerinGimpImg : Current layer in current image
# *****
def create_sepia_effect(inGimpImg, inLayerinGimpImg):
 
	try:
 
		# Convert image to greyscale
		pdb.gimp_desaturate_full(inLayerinGimpImg, DESATURATE_LUMINOSITY)
 
		# Blur the greyscale image
		pdb.plug_in_gauss_iir(inGimpImg, inLayerinGimpImg, 2, True, True)
 
		# Add color layer with soft light mode
		sepiaColorLayer = gimp.Layer(inGimpImg, "sepia color layer", inLayerinGimpImg.width, inLayerinGimpImg.height, inLayerinGimpImg.type, 100, SOFTLIGHT_MODE)
		inGimpImg.add_layer(sepiaColorLayer, 0) 
		pdb.gimp_context_set_background((226,89,42))
		pdb.gimp_edit_fill(sepiaColorLayer, BACKGROUND_FILL)
 
	except Exception as err:
		gimp.message("Unexpected error: " + str(err))
 
 
register(
	"create_sepia_effect",
	"Create Sepia Effect",
	"Adds a sepia effect to an image",
	"ytirahc",
	"Proprietary",
	"2016",
	"/Filters/MDT/Create Sepia Effect",
	"*",
	[],
	[],
	create_sepia_effect)

Apply the Sepia Tone Effect to Multiple Images

We will use BIMP to apply the sepia tone effect to multiple images. The full script must be saved to the GIMP plug-ins directory. If the sepia tone effect plug-in is not showing up in the Filters menu, restart GIMP.

  1. Start BIMP, File -> Batch Image Manipulation…
  2. Specify the create_sepia_effect procedure, Manipulation Set: Add -> Other GIMP procedure… -> python-fu-create-sepia-effect
  3. Click OK
  4. Choose the input images either by files or directories, Input files and Options
  5. Select the output directory where the results will be saved, Output folder
  6. Click Apply

BIMP will apply the sepia tone effect to each input image and save the results to the output folder.

Coming Up …

Our mini-series exploring image batch processing will continue with ImageMagick.

Further Reading

  1. BIMP (Batch Image Manipulation Plugin)
  2. Script-Fu and plug-ins for the GIMP
  3. GIMP Python Documentation
  4. GIMP website

 

Leave a Reply

Your email address will not be published. Required fields are marked *