Adding text captions to images

Hi,

I’m a total newbie. I’ve been searching for a utility to embed visible text captions to thousands of images and there appears to be no commercial solution for my problem.

I’m looking for a way to batch add text captions or watermark to images. Is there a way to add a small border at the bottom of images where the text captions can be placed? I would also like to be able to automatically add variable file names ie: Photos 2005 Christmas: “filename”

thanks for your help.

cg

If you are using Tiger I have written an Automator action that draws text onto image files. At this point it doesn’t do things like file names though I have been thinking about adding it.

The action was written using AppleScript, it is free and requires iMagine Photo which is also free.

The action is included with the three actions in this package.
http://automatoractions.com/files/imaginephotoautomatoractions1.0.html

You can find the download link for iMagine Photo from my website mentioned below.

I have also done a few other actions since I released that package which are listed in the automator actions section of the macscripter website. http://automatoractions.com

If you are not using Tiger or the action does not meet your needs I might be able to do an applescript droplet for you. If that is the case are all your image files JPEGs or are they a mixture of formats.

Kevin

Thanks for the reply ktam. I’m currently using Panther.

I definitely need to be able to include the filename. In fact the flexibility to be able to truncate the filename ie:

“Christmas 2005: Santa01” instead of “Chrismas 2005: dcs_Santa01.jpg” will be another option I would like.

Is what I need difficult to do?

cg

If you’re familiar with the command line, you should try ImageMagick.

It’s easy, but not fast in Photoshop…are you currently using Photoshop?
-N

Save the following script as an application, and then drop your image files onto the script.

I hope it does what you want.

If you need anything just reply and I’ll see what I can do. I forgot to mention you will need iMagine Photo to use the following script. iMagine Photo is free and you can download it from:

http://www.yvs.eu.com/downloading.html

Kevin


property pBackgroundColor : {65535, 65535, 65535} -- white
property pTextColor : {0, 0, 0} -- black
property pFontSize : 24
property pFont : "Verdana"
property pExportFormat : "JPEG" -- currently ignored, assumes "JPEG"
property pAddFileNameToString : true
property pRemoveExtension : true
property pTextToDraw : "Copyright me: "
property pCopyExif : false

-- This script will replace the contents of the original file.

on run
	set pTextToDraw to (text returned of (display dialog "Enter the text to draw before the file name: " default answer pTextToDraw))
	set theFile to choose file with prompt "Choose the file to add the text to: "
	ProcessFile(theFile)
end run

on open theseFiles
	set pTextToDraw to (text returned of (display dialog "Enter the text to draw before the file name: " default answer pTextToDraw))
	repeat with thisFile in theseFiles
		my ProcessFile(thisFile)
	end repeat
end open

on ProcessFile(thisFile)
	if the number of characters in pTextToDraw is equal to 0 and pAddFileNameToString is equal to false then
		return
	end if
	tell application "iMagine Photo"
		set thisImporter to import graphic thisFile
		if the component error of thisImporter is not equal to 0 then
			-- there was an error importing the graphic file, just return.
			close thisImporter
			return
		end if
		set theprops to the properties of thisImporter
		set fileName to ""
		if pAddFileNameToString is true then
			set fileName to the file name of theprops as string
			if fileName contains "." and pRemoveExtension is true then
				set AppleScript's text item delimiters to "."
				set fileName to items 1 thru -2 of (every text item of fileName) as string
				set AppleScript's text item delimiters to ""
			end if
		end if
		set stringToDraw to pTextToDraw & fileName
		set textRecord to {class:standard text, font:pFont, font size:pFontSize, drawing text:stringToDraw, start from:top left, start point:{0, 0}, color:pTextColor, background color:pBackgroundColor}
		set {textWidth, textHeight} to get text dimensions with properties textRecord
		set {x, y, imageWidth, imageHeight} to the natural bounds of theprops
		set thisDocument to make new graphic document with properties {dimensions:{imageWidth, imageHeight + textHeight}}
		set the drawing destination of thisImporter to thisDocument
		draw thisImporter
		set the export file location of thisDocument to thisFile -- ie replace the contents
		if pCopyExif is true then
			set the export exif data of thisDocument to the exif data of thisImporter
		end if
		close thisImporter
		set the start point of textRecord to {(imageWidth - textWidth) div 2, imageHeight}
		tell thisDocument to create composition element with properties {class:filled rectangle, bounds rectangle:{0, imageHeight, imageWidth, imageHeight + textHeight}, color:pBackgroundColor}
		tell thisDocument to create composition element with properties textRecord
		export thisDocument
		close thisDocument
	end tell
end ProcessFile

Thank you very much ktam!! This is exactly what I need. It’s working great and much faster than doing it through PS

I have a few questions/requests:

Add a space between the pTextToDraw and the filename
Ability to change the position of the text from bottom center to bottom left
Keep icc profiles intact if possible
Maintain grayscale images as grayscale instead of getting converted to rgb
Have the ability to truncate the beginning of the filename by specifying the number of characters

Thanks again,

cg

How about this then.

You have to manually edit the number of characters that you want to remove by replacing 0 after pNumFilenamePrefixCharsToRemove with your own value, I haven’t tested that part of the script. I also haven’t tested drawing the text from the left but it should work.

If you original image file is a cmyk image iMagine Photo will not create a cmyk image (it can’t). iMagine Photo will attempt to keep the icc profile. Let me know how that bit goes, because I am not sure in what situations the copying of a profile breaks.

If the original image is a 8 bit grayscale, a 8 bit grayscale image will be created.


property pBackgroundColor : {65535, 65535, 65535} -- white
property pTextColor : {0, 0, 0} -- blackk
property pFontSize : 24
property pFont : "Verdana"
property pExportFormat : "JPEG" -- currently ignored, assumes "JPEG"
property pAddFileNameToString : true
property pRemoveExtension : true
property pTextToDraw : "Copyright me: "
property pCopyExif : false
property pCopyProfile : true
property pNumFilenamePrefixCharsToRemove : 0

-- This script will replace the contents of the original file.

on run
	set pTextToDraw to (text returned of (display dialog "Enter the text to draw before the file name: " default answer pTextToDraw))
	set theFile to choose file with prompt "Choose the file to add the text to: "
	ProcessFile(theFile)
end run

on open theseFiles
	set pTextToDraw to (text returned of (display dialog "Enter the text to draw before the file name: " default answer pTextToDraw))
	repeat with thisFile in theseFiles
		my ProcessFile(thisFile)
	end repeat
end open

on ProcessFile(thisFile)
	if the number of characters in pTextToDraw is equal to 0 and pAddFileNameToString is equal to false then
		return
	end if
	tell application "iMagine Photo"
		set thisImporter to import graphic thisFile
		if the component error of thisImporter is not equal to 0 then
			-- there was an error importing the graphic file, just return.
			close thisImporter
			return
		end if
		set theprops to the properties of thisImporter
		set fileName to ""
		if pAddFileNameToString is true then
			set fileName to the file name of theprops as string
			if fileName contains "." and pRemoveExtension is true then
				set AppleScript's text item delimiters to "."
				set fileName to items 1 thru -2 of (every text item of fileName) as string
				set AppleScript's text item delimiters to ""
			end if
			if pNumFilenamePrefixCharsToRemove is not equal to 0 then
				set numChars to the number of characters in fileName
				if numChars is greater than pNumFilenamePrefixCharsToRemove then
					set fileName to (characters (pNumFilenamePrefixCharsToRemove + 1) thru numChars of fileName) as string
				end if
			end if
			set fileName to " " & fileName -- added a space.
		end if
		set stringToDraw to pTextToDraw & fileName
		set textRecord to {class:standard text, font:pFont, font size:pFontSize, drawing text:stringToDraw, start from:top left, start point:{0, 0}, color:pTextColor, background color:pBackgroundColor}
		set {textWidth, textHeight} to get text dimensions with properties textRecord
		set {x, y, imageWidth, imageHeight} to the natural bounds of theprops
		set thisDocument to make new graphic document with properties {dimensions:{imageWidth, imageHeight + textHeight}}
		set the drawing destination of thisImporter to thisDocument
		set DONTgamma correct of thisImporter to true
		set DONTcolor match of thisImporter to true
		draw thisImporter
		set the export file location of thisDocument to thisFile -- ie replace the contents
		if pCopyExif is true then
			set the export exif data of thisDocument to the exif data of thisImporter
		end if
		close thisImporter
		--set the start point of textRecord to {(imageWidth - textWidth) div 2, imageHeight}
		set the start point of textRecord to {0, imageHeight} -- the left edge of the image.
		tell thisDocument to create composition element with properties {class:filled rectangle, bounds rectangle:{0, imageHeight, imageWidth, imageHeight + textHeight}, color:pBackgroundColor}
		tell thisDocument to create composition element with properties textRecord
		if the bit depth of theprops is equal to 40 then -- greyscale 8 bit.
			set the export compression depth of thisDocument to 40
		end if
		if pCopyProfile is true then
			set the export icc profile of thisDocument to thisFile
		end if
		export thisDocument
		close thisDocument
	end tell
end ProcessFile

Kevin

Thanks Kevin.
It’s working great. ICC profiles are properly preserved for both colour and grayscale images. Text are now drawn bottom left.

Great work! Thanks again,

cg

A small update:

I have added the script to scriptbuilders with some minor changes, the changes are not related to anything that cg needed so he doesn’t need to get the updated script.

The script is in the multimedia section of scriptbuilders so look for: “Draw Caption On Image”

http://scriptbuilders.net/cat.php?category_list=9

Kevin