Apr
12

Author:

Comment

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

 

Apr
11

Author:

Comment

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

This is part 2 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 Adobe Photoshop. 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 Adobe Photoshop CC 2015.

Batch Processing in Photoshop

Photoshop offers two ways to process images in batch:

  • Batch accessible via File -> Automate -> Batch…
  • Image Processor accessible via File -> Scripts -> Image Processor…

Batch and Image Processor are almost identical in functionality, except Batch requires an Action while for the Image Processor an Action is optional. An Action is a recorded series of tasks performed on image. Actions can then be “played” or executed on other images. We will create Actions to resize and apply the sepia tone effect to our images.

Resizing Images

If the final pixel height & width are known, resizing images is easy to do with the Image Processor. However, 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 several ways to approach this:

  • Create an Action for each resize percentage, and then run separately in batch
  • Write a script that takes an input directory of images and then creates & saves the resized images to (preferably) a different directory
  • Create an Action which runs a script on an image that creates & saves the resized images to a specified directory. The Action is then executed in batch, with the input directory of images specified in the batch dialog

We will go with the last option, which is a combination of the first two options.

nyc skyline resizing illustration 04082016Original Image Scaled to 75%, 50% and 25%

Resizing One Image to Several Sizes

The following Javascript code, resizing-to-multiple.js, scales the current Photoshop image into three (3) different sizes, 75%, 50% & 25%, and saves them into the output directory, saveDir. This can be tested on one image by saving the script to a file (be sure to change the output directory to a valid directory on your system), select the script through File -> Scripts -> Browse… which will run it on the current image.

// Copyright (c) 2016, ytirahc, www.mobiledevtrek.com
// All rights reserved. Copyright holder cannot be held liable for any damages. 
// 
// Distributed under the Apache License (ASL). 
// http://www.apache.org/licenses/
// *****
// Description: This file is a script for Adobe Photoshop (tested with Photoshop CC 2015). 
// The current active image in Photoshop will be resized by the specified percentages
// in the array scaleFactor and will save those files to the specified directory, saveDir. 
//
// Usage: File -> Scripts -> Browse... to locate the script and execute it
// *****

var scaleFactor = [75, 50, 25];  // Scale factor as percentage of original image
var saveDir = "~/Documents/work/"; // Directory in which to save resized images

// Create resized image for all specified scale factors
for (var scaleFactorIndex in scaleFactor) 
{
	ResizeToScaleFactor(saveDir, scaleFactor[scaleFactorIndex])
}

// *****
// ResizeToScaleFactor
//
// Description: Resizes an image according to specified scale factor and saves it
//
// Parameters:
// 		inSaveDir: Directory in which to save resized image
//		inScaleFactor: Scale factor as a percentage in which to resize image
// *****
function ResizeToScaleFactor(inSaveDir, inScaleFactor) 
{

	var doc;  // Reference to the active document
	var duplicateDoc;  // Reference to a copy of the active document
	var imageName; // The name of the current document, without extension
	var saveFN; // The full file path and name of the image to be saved
	var saveFNOptions; // The save options

	// Reference to current, active document
	doc = app.activeDocument;
	
	// Duplicate document
	duplicateDoc = doc.duplicate();

	// Resize image according to specified scale factor
	duplicateDoc.resizeImage(UnitValue(inScaleFactor,"%"),null,null,ResampleMethod.BICUBIC);

	// Save the resized image as a jpg
	imageName = (doc.name).split(".")[0];
	saveFN = new File(inSaveDir + imageName + "_" + inScaleFactor + "percent.jpg" );
	saveFNOptions = new JPEGSaveOptions();
	saveFNOptions.embedColorProfile = true;
	saveFNOptions.formatOptions = FormatOptions.STANDARDBASELINE;
	saveFNOptions.matte = MatteType.NONE;
	saveFNOptions.quality = 9;
	duplicateDoc.saveAs(saveFN, saveFNOptions, true, Extension.LOWERCASE);

	// Close the duplicate image view without a save as dialog box
	duplicateDoc.close(SaveOptions.DONOTSAVECHANGES)

}

This code is also available here. Further information on the Photoshop JavaScript API can be found in the reference document.

Resizing Multiple Images to Several Sizes

To resize multiple images at once, we create an Action that will be executed in the Image Processor.

Creating An Action to Run the Script

  1. Open an image in Photoshop
  2. Open the Actions window, Windows -> Actions
  3. Create a new Action and name it “Resize & Save Images”
  4. Click Record
  5. Select the script to run it, File -> Scripts -> Browse…
  6. Click on the Stop button in the Actions window to halt the recording of actions

Now we have an Action that runs the script which scales an image to several sizes. We can use this Action in our batch processing. This step only has to be completed once as the Action is saved and reusable.

Running the Script on Multiple Images

  1. Open the Batch dialog, File -> Automate -> Batch
    • Play -> Action: Resizes & Save
    • Source: Folder
    • Source -> Choose: Select the directory where the input image files are located
    • Destination -> Save and Close
  2. Click OK

Images will flash on and off the screen as they are open and closed during processing.

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.

As with resizing, we create an Action that we will run on a directory of images. No scripting required.

Sepia Tone EffectSepia Tone Effect Applied to Original Image

Creating An Action to Apply the Sepia Tone Effect

  1. Open an image in Photoshop
  2. Open the Actions window, Windows -> Actions
  3. Create a new Action and name it “Sepia Tone Effect”
  4. Click Record
  5. Convert the image to greyscale, Image -> Adjustments -> Desaturate
  6. Smooth it a tad, Filter -> Blur -> Gaussian Blur
    • Radius: 2
  7. Add a new layer, Layer -> New Fill Layer -> Solid Color
    • Mode: Soft Light [Click OK]
    • #: e2592a
  8. Halt the recording of actions by clicking on the Stop button in the Actions window

With the Action Sepia Tone Effect saved, we will apply it to a group of images using the Image Processor.

Apply the Sepia Tone Effect to Multiple Images

  1. Open the Image Processor dialog, File -> Scripts -> Image Processor
    • Select the images to process -> Select Folder: Choose the directory where the input image files are located
    • Select location to save processed images – > Select Folder: Choose the directory where the output files are to be saved
    • File Type: Click Save as JPEG
    • Preferences -> Run Action: Choose Sepia Tone Effect
  2. Click Run

Your processed images will be saved in the output directory you chose under a subdirectory called “JPEG”.

Coming Up …

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

Further Reading

  1. Adobe Photoshop Scripting References for Javascript, Applescript and VBScript
  2. Photoshop Help: Process a Batch of Files
  3. Photoshop Help: Creating Actions
  4. Creating Batch Actions

 

Apr
8

Author:

Comment

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

When working with a group of images, sometimes we want to manipulate each image within the group in the the same way. For example, resizing to thumbnails or applying a filter to smooth out noise. However, working on one image at a time is quite tedious & time consuming and prone to error. How can this be made simpler?

Over the next several posts, we will explore how we can apply simple or complex modifications to any number of images at the same time. This is referred to as batch processing.

How to Process Images in Batch

Batch processing of images is the automatic application of identical changes to all images at the same time (or in the same run). For example, say I had 10 photos of my adventures at the zoo, but they are too large to share with my animal loving friends & family as e-mail attachments. While I could open, resize, save & close each image individually, my eyes would glaze over after the first few. I would much rather create a set of commands that will be applied to each image automatically.

This requires a graphics editing program that supports processing images in batch, or writing a script using image processing libraries. We will be looking at batch processing with Adobe Photoshop, GIMP, ImageMagick, PIL (Python Imaging Library) and OpenCV. The first two are editing programs and the latter are libraries. All require coding to manipulate images in batch. However, Photoshop offers an all gui approach which relies on recording of a set of user actions that then can be “played” (or executed) on any image.

When coding is required, we will write Python scripts. Since Photoshop requires scripts to be written in Javascript, VBScript or AppleScript, we will use Javascript instead.

Image Manipulations: Resizing & Applying the Sepia Effect

We will implement the following manipulations on our images:

  • resize each image into three (3) different sizes: 75%, 50%, 25%, of the originalIllustration of Image Resizing
  • apply a sepia tone effect, which is a reddish brown hue that gives the photo an aged lookSepia Tone Effect Illustration

Resizing or scaling an image is supported in all image editors and libraries. Photoshop and ImageMagick already have sepia functionality available, but we will be applying our own algorithm through image desaturation and blending.

Sepia Tone Effect Algorithm

The sepia tone effect lends an old, antique-ish look to a photo. The following steps will be implemented to achieve a sepia tone effect.

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

The soft light blend mode provides an effect similar to shining a diffused spotlight on the image. When blending is not supported natively, we will implement it ourselves. Luckily, the math is pretty straightforward. For this we will use the W3C equations for the soft light blending mode.

Coming Up …

Our next post will explore batch processing in Adobe Photoshop.

Further Reading

  1. Blending mode definitions in Photoshop
  2. A description of blend modes

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

Monday, April 11, 2016

This is part 2 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….

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

Friday, April 8, 2016

When working with a group of images, sometimes we want to manipulate each image within the group in the the same way. For example, resizing to thumbnails or…