Photoshop Script

Hi -

I’m new to Applescript, and I’m trying to write a script that finds all of the files in a folder or subfolder(s) that are larger than 999kb and then opens them in Photoshop and does a Save As with LZW compression.

Here’s what I have so far, but nothing happens. Also if there is a way to make sure that the finder is even selecting the right files that would be great for troubleshooting the script.

–Process all files in folders dropped in this script
– (when saved as an applet)
– Save each file larger than 999kb as a TIFF file with LZW compression
on run
tell me to open {choose folder}
end run
on open droppedItems
repeat with anItem in droppedItems
tell application “Finder”
set fileSize to physical size of anItem
set the units to “kilobytes”
– Make sure each item processed by this script is a folder
if class of item anItem is not folder then
– Not a folder, notify the user of the error
display dialog “Please drop only folders on script”
else
– A folder, get Tif files and process them
set fileList to (every file of anItem where size is greater than 999) as alias list
end if
reveal fileList
end tell
SaveFileAsTIFF(fileList)
end repeat
end open

– filelist is a list of aliases to TIFF files
on SaveFileAsTIFF(fileList)
repeat with aFile in fileList
tell application “Adobe Photoshop CS3”
open aFile
save current document as TIFF with options {class:TIFF save options, image compression:LZW}
close current document saving no
end tell
end repeat
end SaveFileAsTIFF

As far as i can tell, your droplet (applet) is not being called. When you create a droplet, anything you drop on it automatically gets stored in a variable, you do not need to have “choose folder”

For instance, a folder action is called like this:

on adding folder items to this_folder after receiving added_items

added_items is already a list of every file that has been added to the folder. Try apples own documentation on folder actions.

This is not a legitimate applescript statement. All sizes in OSX are in bytes, therefore you will need to convert them to kilobytes before you can base if statements on them.

I use this niftly little conversion tool:


property base_file_size : 1024 --some would use 1000
--converts file size to correct size
on get_file_size(the_size)
	if the_size > (base_file_size ^ 4) then
		set {div_1, the_unit} to {(base_file_size ^ 4), "TB"}
	else if the_size is greater than or equal to (base_file_size ^ 3) then
		set {div_1, the_unit} to {(base_file_size ^ 3), "GB"}
	else if the_size is greater than or equal to (base_file_size ^ 2) then
		set {div_1, the_unit} to {(base_file_size ^ 2), "MB"}
	else if the_size is greater than or equal to base_file_size then
		set {div_1, the_unit} to {base_file_size, "KB"}
	else
		set {div_1, the_unit} to {1, "B"}
	end if
	set the_size to (((the_size div div_1) & "." & ((the_size mod div_1) div (div_1 / 10)) as string) as real) as string
	if the_size ends with ".0" then set the_size to (text 1 thru -3 of the_size)
	return (the_size & " " & the_unit as string)
end get_file_size

(I can’t claim credit for writing this, I found it on this very forum. Can’t remember who I got it from but cheers anyway.)

When you’re testing, its better to set up your functions in a standard applescript, then, once you have it all working well, convert it to a folder action. Makes for easier testing and error solving.

Good luck. Hope that helped.

Hi There,

A couple of questions.

  1. Are wanting to process only originals that are TIFF or any image over 999 KB?

  2. Are you set on using Photoshop?

Below is a solution that currently runs as a script or applet. It can be made to be drag and drop or double clicked or both or a folder action. It probably does more then you need but it will save a TIFF with LZW as well as other formats. It will leave all originals in place as it copies the files then puts the converted images in another folder both on your desktop. This currently uses SIPS (scriptable image processing system) which is a command line tool so it’s pretty fast and works in the background. This script could be pretty easily changed to use Photoshop instead and only process certain file types in case you want to process only TIFF’s.

This version will process any file over 1MB (1024 KB) but could be tweaked more if the 999 KB value is that important.

Some info.
Code in the “on run” handler is executed when the user double clicks the applet or runs it from Script Editor
Code in the “on open draggedItems” handler is executed when the user drops folders or files on the applet.
Code in the “on adding folder items” is used for folder actions as Chuckles mentioned.

Give it a go.


property done_foldername : "Converted Images"
property originals_foldername : "Original Images"
property newimage_extension : ""
property type_list : {"JPEG", "GIFf", "PNGf", "PICT", "TIFF", "PDF", "PSD", "BMP", "TGA"}
property extension_list : {"jpg", "jpeg", "gif", "png", "pict", "pct", "tif", "tiff", "pdf", "psd", "bmp", "tga"}
property desktop_path : (path to desktop)
property my_format : ""
property my_formatOptions : ""
property sScript : ""
property base_file_size : 1024 --some would use 1000

on run
	
	display dialog "This application will:" & return & "1) Copy images in formats:" & return & "JPEG, TIFF, GIF, PNG, PICT, PDF, PSD, BMP, TGA" & return & return & "2) Convert images larger then 1mb into:" & return & "TIFF, JPEG, PNG, PSD, PICT, BMP or TGA" buttons {"Cancel", "Continue"} default button 2 with title "Convert Images" with icon note
	choose folder with prompt "Choose a folder of images to process:"
	set myFolder to result as list
	choose from list {"TIFF", "JPEG", "PNG", "PSD", "PICT", "BMP", "TGA"} default items {"TIFF"} with title "Convert Images Into..." without empty selection allowed
	copy the result as list to {the selected_format}
	if selected_format = false then
		display dialog "The user has canceled the script" buttons {"Cancel"} default button 1 with title "Convert Images" with icon caution
	else if selected_format = "TIFF" then
		set my_format to "-s format tiff "
		set newimage_extension to "tif"
		set my_formatOptions to {"LZW", "None"}
		choose from list my_formatOptions default items {"LZW"} with title "Choose Compression" without empty selection allowed
		copy the result as list to {the my_formatOptions}
		if my_formatOptions = false then
			display dialog "The user has canceled the script" buttons {"Cancel"} default button 1 with title "Convert Images" with icon caution
		else if my_formatOptions = "None" then
			set my_formatOptions to ""
		else if my_formatOptions = "LZW" then
			set my_formatOptions to "-s formatOptions lzw "
		end if
		set sScript to "sips " & my_format & my_formatOptions
	else if selected_format = "JPEG" then
		set my_format to "-s format jpeg "
		set newimage_extension to "jpg"
		set my_formatOptions to {"Low", "Normal", "High", "Best"}
		choose from list my_formatOptions default items {"Low"} with title "Choose Compression" without empty selection allowed
		copy the result as list to {the my_formatOptions}
		if my_formatOptions = false then
			display dialog "The user has canceled the script" buttons {"Cancel"} default button 1 with title "Convert Images" with icon caution
		else if my_formatOptions = "Low" then
			set my_formatOptions to "-s formatOptions low "
		else if my_formatOptions = "Normal" then
			set my_formatOptions to "-s formatOptions normal "
		else if my_formatOptions = "High" then
			set my_formatOptions to "-s formatOptions high "
		else if my_formatOptions = "Best" then
			set my_formatOptions to "-s formatOptions best "
		end if
		set sScript to "sips " & my_format & my_formatOptions
	else if selected_format = "PNG" then
		set my_format to "-s format png "
		set my_formatOptions to ""
		set newimage_extension to "png"
		set sScript to "sips " & my_format & my_formatOptions
	else if selected_format = "PSD" then
		set my_format to "-s format psd "
		set my_formatOptions to ""
		set newimage_extension to "psd"
		set sScript to "sips " & my_format & my_formatOptions
	else if selected_format = "PICT" then
		set my_format to "-s format pict "
		set my_formatOptions to ""
		set newimage_extension to "pct"
		set sScript to "sips " & my_format & my_formatOptions
	else if selected_format = "BMP" then
		set my_format to "-s format bmp "
		set my_formatOptions to ""
		set newimage_extension to "bmp"
		set sScript to "sips " & my_format & my_formatOptions
	else if selected_format = "TGA" then
		set my_format to "-s format tga "
		set my_formatOptions to ""
		set newimage_extension to "tga"
		set sScript to "sips " & my_format & my_formatOptions
	end if
	
	tell application "Finder"
		if not (exists folder done_foldername of desktop_path) then
			make new folder at desktop_path with properties {name:done_foldername}
		end if
		set the results_folder to (folder done_foldername of desktop_path) as alias
		if not (exists folder originals_foldername of desktop_path) then
			make new folder at desktop_path with properties {name:originals_foldername}
			set current view of container window of desktop_path to list view
		end if
		set the originals_folder to folder originals_foldername of desktop_path
		set master_list to {}
		repeat with this_item in myFolder
			set item_info to properties of this_item
			if kind of item_info is "Folder" then
				try
					set master_list to every file of entire contents of folder this_item as alias list
				on error
					
					set master_list to every file of entire contents of folder this_item as alias as list
				end try
			else
				set end of master_list to this_item
			end if
		end repeat
	end tell
	try
		repeat with this_item in master_list
			set the item_info to the info for this_item
			set the_size to (the size of item_info)
			my get_file_size(the_size)
			set the_size to result
			set {the_sizeNum, the_unitIncr} to {(the first item of the_size as string), (the second item of the_size as string)}
			
			if (alias of the item_info is false and the file type of the item_info is in the type_list) or (the name extension of the item_info is in the extension_list) then
				
				tell application "Finder"
					my resolve_conflicts(this_item, originals_folder, "")
					set the new_name to my resolve_conflicts(this_item, results_folder, newimage_extension)
					set the source_file to (duplicate this_item to the originals_folder with replacing) as alias
				end tell
				--if ((the_sizeNum as number) > "999.0") and the_unitIncr is "KB" then
				if the_unitIncr is not "KB" then
					process_item(source_file, new_name, results_folder)
				end if
			end if
		end repeat
	on error error_message number error_number
		if the error_number is not -128 then
			tell application "Finder"
				activate
				display dialog error_message buttons {"Cancel"} default button 1 giving up after 120 with icon caution
			end tell
		end if
	end try
	set converted_path to (path to desktop) & "Converted Images"
	set originals_path to (path to desktop) & "Original Images"
	tell application "Finder"
		activate
		display dialog "The images have been converted to " & selected_format & " format." buttons {"Quit", "Open Folders"} default button 1 with title "Success!" with icon note
	end tell
	copy the result as list to {the button_pressed}
	if button_pressed contains "Open Folder" then
		my open_converted(converted_path)
		my open_originals(originals_path)
	end if
end run

on resolve_conflicts(this_item, target_folder, new_extension)
	tell application "Finder"
		set the file_name to the name of this_item
		set file_extension to the name extension of this_item
		if the file_extension is "" then
			set the trimmed_name to the file_name
		else
			set the trimmed_name to text 1 thru -((length of file_extension) + 2) of the file_name
		end if
		if the new_extension is "" then
			set target_name to file_name
			set target_extension to file_extension
		else
			set target_extension to new_extension
			set target_name to (the trimmed_name & "." & target_extension) as string
		end if
		if (exists document file target_name of target_folder) then
			set the name_increment to 1
			repeat
				set the new_name to (the trimmed_name & "." & (name_increment as string) & "." & target_extension) as string
				if not (exists document file new_name of the target_folder) then
					-- rename to conflicting file
					set the name of document file target_name of the target_folder to the new_name
					exit repeat
				else
					set the name_increment to the name_increment + 1
				end if
			end repeat
		end if
	end tell
	return the target_name
end resolve_conflicts

on get_file_size(the_size)
	if the_size > (base_file_size ^ 4) then
		set {div_1, the_unit} to {(base_file_size ^ 4), "TB"}
	else if the_size is greater than or equal to (base_file_size ^ 3) then
		set {div_1, the_unit} to {(base_file_size ^ 3), "GB"}
	else if the_size is greater than or equal to (base_file_size ^ 2) then
		set {div_1, the_unit} to {(base_file_size ^ 2), "MB"}
	else if the_size is greater than or equal to base_file_size then
		set {div_1, the_unit} to {base_file_size, "KB"}
	else
		set {div_1, the_unit} to {1, "B"}
	end if
	set the_size to (((the_size div div_1) & "." & ((the_size mod div_1) div (div_1 / 10)) as string) as real) as string
	if the_size ends with ".0" then set the_size to (text 1 thru -3 of the_size)
	--return (the_size & " " & the_unit as string)
	return {the_size, the_unit}
end get_file_size

on process_item(source_file, new_name, results_folder)
	try
		set the target_path to ((results_folder as string) & new_name) as string
		with timeout of 900 seconds
			
			do shell script (sScript & "\"" & (POSIX path of source_file) & "\"" & " --out " & "\"" & (POSIX path of target_path) & "\"")
		end timeout
	on error error_message
		tell application "Finder"
			activate
			display dialog error_message buttons {"Cancel"} default button 1 giving up after 120 with icon caution
		end tell
	end try
end process_item

on open_originals(originals_path)
	tell application "Finder"
		open the folder (originals_path as string)
		set the toolbar visible of the window originals_foldername to false
		set properties of the icon view options of the window "Original Images" to {arrangement:arranged by name, icon size:128, shows icon preview:true, shows item info:true}
		set bounds of the window originals_foldername to {510, 50, 1010, 500}
	end tell
end open_originals

on open_converted(converted_path)
	tell application "Finder"
		open the folder (converted_path as string)
		set the toolbar visible of the window done_foldername to false
		set properties of the icon view options of the window "Converted Images" to {arrangement:arranged by name, icon size:128, shows icon preview:true, shows item info:true}
		set bounds of the window done_foldername to {10, 50, 500, 500}
	end tell
end open_converted

Chuckles66: I like the get_file_size handler :slight_smile:

Regards,
MT

This is great!!

Just one question…I have a main folder with multiple subfolders that need the conversion done. So I’d like the files that get converted to just save over themselves in their respective folders. This way I can drop the main folder on the script and just walk away, rather than having to drop each subfolder and then sort through and move files afterwards.

He Again,

Try this one. It will save the new file in the same location as the original. If the original is a TIFF and you are saving TIFF it will overwrite the old, because the extension doesn’t change, otherwise the originals will remain intact.


property newimage_extension : ""
property type_list : {"JPEG", "GIFf", "PNGf", "PICT", "TIFF", "PDF", "PSD", "BMP", "TGA"}
property extension_list : {"jpg", "jpeg", "gif", "png", "pict", "pct", "tif", "tiff", "pdf", "psd", "bmp", "tga"}
property my_format : ""
property my_formatOptions : ""
property sScript : ""
property base_file_size : 1024 --some would use 1000

on run
	-- Dialog explaining scripts intentions
	display dialog "This application will process images larger than 1mb in formats:" & return & "JPEG, TIFF, GIF, PNG, PICT, PDF, PSD, BMP, TGA" & return & return & "2) Images will be converted into your choice of:" & return & "TIFF, JPEG, PNG, PSD, PICT, BMP or TGA" & return & "CAUTION! : Images may be overwritten" buttons {"Cancel", "Continue"} default button 2 with title "Convert Images" with icon note
	
	-- Prompt user to select a folder to process
	choose folder with prompt "Choose a folder of images to process:"
	set myFolder to result as list
	
	choose from list {"TIFF", "JPEG", "PNG", "PSD", "PICT", "BMP", "TGA"} default items {"TIFF"} with title "Convert Images Into..." without empty selection allowed
	copy the result as list to {the selected_format}
	-- Collect info from user to deterime type of file to be generated
	if selected_format = false then
		display dialog "The user has canceled the script" buttons {"Cancel"} default button 1 with title "Convert Images" with icon caution
	else if selected_format = "TIFF" then
		set my_format to "-s format tiff "
		set newimage_extension to "tif"
		set my_formatOptions to {"LZW", "None"}
		choose from list my_formatOptions default items {"LZW"} with title "Choose Compression" without empty selection allowed
		copy the result as list to {the my_formatOptions}
		if my_formatOptions = false then
			display dialog "The user has canceled the script" buttons {"Cancel"} default button 1 with title "Convert Images" with icon caution
		else if my_formatOptions = "None" then
			set my_formatOptions to ""
		else if my_formatOptions = "LZW" then
			set my_formatOptions to "-s formatOptions lzw "
		end if
		set sScript to "sips " & my_format & my_formatOptions
	else if selected_format = "JPEG" then
		set my_format to "-s format jpeg "
		set newimage_extension to "jpg"
		set my_formatOptions to {"Low", "Normal", "High", "Best"}
		choose from list my_formatOptions default items {"Low"} with title "Choose Compression" without empty selection allowed
		copy the result as list to {the my_formatOptions}
		if my_formatOptions = false then
			display dialog "The user has canceled the script" buttons {"Cancel"} default button 1 with title "Convert Images" with icon caution
		else if my_formatOptions = "Low" then
			set my_formatOptions to "-s formatOptions low "
		else if my_formatOptions = "Normal" then
			set my_formatOptions to "-s formatOptions normal "
		else if my_formatOptions = "High" then
			set my_formatOptions to "-s formatOptions high "
		else if my_formatOptions = "Best" then
			set my_formatOptions to "-s formatOptions best "
		end if
		set sScript to "sips " & my_format & my_formatOptions
	else if selected_format = "PNG" then
		set my_format to "-s format png "
		set my_formatOptions to ""
		set newimage_extension to "png"
		set sScript to "sips " & my_format & my_formatOptions
	else if selected_format = "PSD" then
		set my_format to "-s format psd "
		set my_formatOptions to ""
		set newimage_extension to "psd"
		set sScript to "sips " & my_format & my_formatOptions
	else if selected_format = "PICT" then
		set my_format to "-s format pict "
		set my_formatOptions to ""
		set newimage_extension to "pct"
		set sScript to "sips " & my_format & my_formatOptions
	else if selected_format = "BMP" then
		set my_format to "-s format bmp "
		set my_formatOptions to ""
		set newimage_extension to "bmp"
		set sScript to "sips " & my_format & my_formatOptions
	else if selected_format = "TGA" then
		set my_format to "-s format tga "
		set my_formatOptions to ""
		set newimage_extension to "tga"
		set sScript to "sips " & my_format & my_formatOptions
	end if
	
	-- Sort the folders contents to determine which files to process
	tell application "Finder"
		set master_list to {}
		repeat with this_item in myFolder
			set item_info to properties of this_item
			if kind of item_info is "Folder" then
				try
					set master_list to every file of entire contents of folder this_item as alias list
				on error
					
					set master_list to every file of entire contents of folder this_item as alias as list
				end try
			else
				set end of master_list to this_item
			end if
		end repeat
	end tell
	try
		repeat with this_item in master_list
			set the item_info to the info for this_item
			set the_size to (the size of item_info)
			my get_file_size(the_size)
			set the_size to result
			set {the_sizeNum, the_unitIncr} to {(the first item of the_size as string), (the second item of the_size as string)}
			
			if (alias of the item_info is false and the file type of the item_info is in the type_list) or (the name extension of the item_info is in the extension_list) then
				
				tell application "Finder"
					my resolve_conflicts(this_item, "")
					set the new_name to my resolve_conflicts(this_item, newimage_extension)
					set the source_file to this_item as alias
					set results_folder to (container of this_item as string)
					--return results_folder
				end tell
				if the_unitIncr is not "KB" then
					process_item(source_file, new_name, results_folder)
				end if
			end if
		end repeat
	on error error_message number error_number
		if the error_number is not -128 then
			tell application "Finder"
				activate
				display dialog error_message buttons {"Cancel"} default button 1 giving up after 120 with icon caution
			end tell
		end if
	end try
	set converted_path to (path to desktop) & "Converted Images"
	set originals_path to (path to desktop) & "Original Images"
	tell application "Finder"
		activate
		display dialog "The images have been converted to " & selected_format & " format." buttons {"Quit"} default button 1 with title "Success!" with icon note
	end tell
end run

-- Handler to create name with new extension
on resolve_conflicts(this_item, new_extension)
	tell application "Finder"
		set the file_name to the name of this_item
		set file_extension to the name extension of this_item
		if the file_extension is "" then
			set the trimmed_name to the file_name
		else
			set the trimmed_name to text 1 thru -((length of file_extension) + 2) of the file_name
		end if
		if the new_extension is "" then
			set target_name to file_name
			set target_extension to file_extension
		else
			set target_extension to new_extension
			set target_name to (the trimmed_name & "." & target_extension) as string
		end if
	end tell
	return the target_name
end resolve_conflicts

-- Handler to check the file size
on get_file_size(the_size)
	if the_size > (base_file_size ^ 4) then
		set {div_1, the_unit} to {(base_file_size ^ 4), "TB"}
	else if the_size is greater than or equal to (base_file_size ^ 3) then
		set {div_1, the_unit} to {(base_file_size ^ 3), "GB"}
	else if the_size is greater than or equal to (base_file_size ^ 2) then
		set {div_1, the_unit} to {(base_file_size ^ 2), "MB"}
	else if the_size is greater than or equal to base_file_size then
		set {div_1, the_unit} to {base_file_size, "KB"}
	else
		set {div_1, the_unit} to {1, "B"}
	end if
	set the_size to (((the_size div div_1) & "." & ((the_size mod div_1) div (div_1 / 10)) as string) as real) as string
	if the_size ends with ".0" then set the_size to (text 1 thru -3 of the_size)
	return {the_size, the_unit}
end get_file_size

-- Handler to process each image
on process_item(source_file, new_name, results_folder)
	try
		set the target_path to ((results_folder as string) & new_name) as string
		with timeout of 900 seconds
			
			do shell script (sScript & "\"" & (POSIX path of source_file) & "\"" & " --out " & "\"" & (POSIX path of target_path) & "\"")
		end timeout
	on error error_message
		tell application "Finder"
			activate
			display dialog error_message buttons {"Cancel"} default button 1 giving up after 120 with icon caution
		end tell
	end try
end process_item

Happy Holidays,
MT

YOU ROCK!! :lol:

This will save me sooooo much time.

Thanks again!

Hi MT -

I was working with the script and found that it doesn’t seem to work on folders that are on a server. The folders are on a SAN that I connect to via smb.

The script works great if I copy the folders to my desktop, but since usually there’s at least 2gb of data it would be better if it worked from the fileshare.

Thanks for any help you can provide. I’ll keep looking at it myself to see if I can figure anything out.

Jenn

Hi Jenn,

I tested with my Mac OS X Server using a volume shared over AFP with no problem. I don’t have any SMB shares to test with. Are you getting an error or does it finish like nothing’s wrong but the new files are not there? Is the SAN stand alone or connected to a server? Windows or Mac? Depending on the file path convention for smb shares it may be in the process_item handler where the shell script is called. What is the address you use to connect? smb://Path/to/…? Do you connect from Finder using command + K?

Thanks,
Mark

Hi Again,

I set up a quick smb share with Mac OS X Server 10.4 and had the same issue that you posted. Turns out the issue is the permissions on the share point. If your running it from Mac OS X Server you need to go into Workgroup Manager, click the Sharing button, Click on the Volume. In the pane to the right select Protocols and choose Windows File Settings. At the bottom where it says “Default Permissions for New Files and Folders” is where you need to change your settings. Your user or group must have write privileges for the volume. I changed this and the script worked fine. If your connecting to a Windows server have your IT allow write access for your user or group for that volume.

Good Luck,
MT

Thanks for your advice. It sounds like it is definitely a server thing. I double checked and I do have read/write privileges on the share so it might have to do with the way I connect to it. I think the server name that the Sys Admin had me use is actually an alias and not the actually machine name. I will work with him to see if I can use the actual path instead.