I’m looking for a script that will take an image from the clipboard, adjust the image horizontal size to 3.33" keeping the same proportions, adjust the image resolution to 150dpi, adjust the image brightness to 15% brighter, and the save to image to the desktop using a fixed filename and image file type; example “clippedimage.png” as an example. The image on the clipboard will be roughly 14"x10" at 72 dpi.
I don’t need to select an image, don’t need to save the file anywhere other than the desktop, and I don’t need to change the filename or file type. Thanks!
If I understand the OP’'s post correctly, he wants an AppleScript that will perform four tasks:
Paste an image file from the clipboard to the desktop. The only way I know to do this is GUI scripting.
Rename the image file once on the desktop–that’s easy.
Change the width of the image file to 500 pixels (3.33" x 150 dpi). Both the sips command-line utility and image events will do this.
Change the exposure/brightness of the image file. I don’t know of any way to do this with macOS utilities within an AppleScript, although ImageMagick can do this if installed.
My understanding isn’t that the OP want the image to be pasted to the Desktop but to be saved in a file named “clippedimage.png” on the desktop.
Doing that doesn’t require GUI scripting.
At this time the unique remaining problem is the requirement upon brightness.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 26 janvier 2020 19:28:54
Here is a piece of code adapted from a Shane Stanley’s script.
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
# Adapted from a Shane Stanley's script
set pathToPng to (path to desktop as text) & "clippedimage.png"
my fileFromClipToPath:(pathToPng as «class furl»)
on fileFromClipToPath:thePath
set pb to current application's NSPasteboard's generalPasteboard() -- get pasteboard
-- (pb's types as list) --> {"public.tiff", "NeXT TIFF v4.0 pasteboard type", "dyn.ah62d4rv4gu8zazwuqm10c6xemf1gq54uqm10c6xenv61a3k", "PVPboardInfoPboardType"}
set theData to pb's dataForType:(current application's NSPasteboardTypeTIFF) -- get tiff data off pasteboard
if theData = missing value then error "No tiff data found on clipboard"
# Convert it into png as asked by the OP
set newRep to current application's NSBitmapImageRep's imageRepWithData:theData
set theData to (newRep's representationUsingType:(current application's NSPNGFileType) |properties|:{NSImageInterlaced:false})
set theResult to (theData's writeToURL:thePath atomically:true)
end fileFromClipToPath:
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 26 janvier 2020 21:18:10
That can be done using CoreImage. Here’s your script, suitably adapted:
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "CoreImage"
# Adapted from a Shane Stanley's script
set pathToPng to (path to desktop as text) & "clippedimage.png"
my fileFromClipToPath:(pathToPng as «class furl»)
on fileFromClipToPath:thePath
set pb to current application's NSPasteboard's generalPasteboard() -- get pasteboard
set theData to pb's dataForType:(current application's NSPasteboardTypeTIFF) -- get tiff data off pasteboard
if theData = missing value then error "No tiff data found on clipboard"
set theCIImage to current application's CIImage's imageWithData:theData
set theCIFilter to (current application's CIFilter's filterWithName:"CIColorControls" withInputParameters:{inputBrightness:0.15, inputImage:theCIImage}) -- change brightness to suit
set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))
set newRep to (current application's NSBitmapImageRep's alloc()'s initWithCIImage:theCIImage)
set theData to (newRep's representationUsingType:(current application's NSPNGFileType) |properties|:{NSImageInterlaced:false})
set theResult to (theData's writeToURL:thePath atomically:true)
end fileFromClipToPath:
I tried to add code to change the size as required by the OP.
Here is what I got which is awful but does the job.
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "CoreImage"
# Adapted from a Shane Stanley's script
set pathToPng to (path to desktop as text) & "clippedimage.png"
my fileFromClipToPath:(pathToPng as «class furl»)
on fileFromClipToPath:thePath
set pb to current application's NSPasteboard's generalPasteboard() -- get pasteboard
set theData to pb's dataForType:(current application's NSPasteboardTypeTIFF) -- get tiff data off pasteboard
if theData = missing value then error "No tiff data found on clipboard"
set theCIImage to current application's CIImage's imageWithData:theData
-- grab the rectangle containing the image
set {{x, y}, {oldWidth, oldHeight}} to theCIImage's extent()
-- define the new size
set theWidth to 500
set theHeight to theWidth / oldWidth * oldHeight
set theCIFilter to (current application's CIFilter's filterWithName:"CIColorControls" withInputParameters:{inputBrightness:0.15, inputImage:theCIImage}) -- change brightness to suit
set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))
set newRep to (current application's NSBitmapImageRep's alloc()'s initWithCIImage:theCIImage)
set theData to (newRep's representationUsingType:(current application's NSPNGFileType) |properties|:{NSImageInterlaced:false})
set theResult to (theData's writeToURL:thePath atomically:true)
-- Reload the image to change its size
set theImage to current application's NSImage's alloc()'s initWithContentsOfURL:thePath -- load the file as an NSImage
set newImage to current application's NSImage's alloc()'s initWithSize:(current application's NSMakeSize(theWidth, theHeight)) -- make new blank image
-- draw from original to new
newImage's lockFocus()
theImage's drawInRect:{origin:{x:0, y:0}, |size|:{width:theWidth, height:theHeight}} fromRect:(current application's NSZeroRect) operation:(current application's NSCompositeSourceOver) fraction:1.0
newImage's unlockFocus()
set theData to newImage's TIFFRepresentation() -- get bitmap as data
set newRep to current application's NSBitmapImageRep's imageRepWithData:theData -- make bitmap from data
set theData to (newRep's representationUsingType:(current application's NSPNGFileType) |properties|:{NSImageInterlaced:false})
set theResult to (theData's writeToURL:thePath atomically:true)
end fileFromClipToPath:
I’m sure that changing the size may be done before the first save action but I failed to do it.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 27 janvier 2020 12:17:43
I missed the need to scale. It’s probably more efficient to do it first, and it can be done in CoreImage too:
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "CoreImage"
set pathToPng to (path to desktop as text) & "clippedimage.png"
my fileFromClipToPath:(pathToPng as «class furl»)
on fileFromClipToPath:thePath
set pb to current application's NSPasteboard's generalPasteboard() -- get pasteboard
set theData to pb's dataForType:(current application's NSPasteboardTypeTIFF) -- get tiff data off pasteboard
if theData = missing value then error "No tiff data found on clipboard"
set theCIImage to current application's CIImage's imageWithData:theData
-- grab the rectangle containing the image
set {{x, y}, {oldWidth, oldHeight}} to theCIImage's extent()
-- define the new size
set theWidth to 500 -- points
set theScale to theWidth / oldWidth
set theCIFilter to (current application's CIFilter's filterWithName:"CILanczosScaleTransform" withInputParameters:{inputScale:theScale, inputImage:theCIImage})
set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))
set theCIFilter to (current application's CIFilter's filterWithName:"CIColorControls" withInputParameters:{inputBrightness:0.15, inputImage:theCIImage}) -- change brightness to suit
set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))
set newRep to (current application's NSBitmapImageRep's alloc()'s initWithCIImage:theCIImage)
set theData to (newRep's representationUsingType:(current application's NSPNGFileType) |properties|:{NSImageInterlaced:false})
set theResult to (theData's writeToURL:thePath atomically:true)
end fileFromClipToPath:
Fredrik71. The goal was to save an image, which is on the clipboard, to the desktop. Your suggestion only appears to copy the POSIX path to an image file to the clipboard.
Yvan. My suggestion was to paste (i.e. save) the image file to the desktop and then immediately to rename it to “clippedimage.png”. Shane’s solution does that in one step, which is certainly better, but both accomplish the same thing.
Shane. I opened your script in post 10 in Script Editor and then attempted to use it with a PNG file created with the screencapture utility and with a JPG image from a digital camera. In both cases, I verified that the image files were in the clipboard, and files named clippedimage.png were created on the desktop. I then opened the new desktop image file in Preview and there was no image (just a large icon with “JPEG” and “PNG”). Your script seems to work for other forum members and so I assume this is an issue only for me.
BTW, after copying the PNG image to the clipboard, I ran “clipboard info”, which returned:
I also ran “the clipboard” and it returned the name of the image file.
I tested after copying in the clipboard the contents of : a jpeg, a tiff and a png.
In every cases, the file created on the desktop behaved flawlessly.
My understanding is that you didn’t copied the contents of your files but the files themselves.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 27 janvier 2020 17:31:16
Thanks Yvan. You are absolutely correct. I copied an image to the clipboard and Shane’s script worked as expected. This also explains your statement I mention in Post 13.
Here is a script which treat both cases:
– the clipboard contain a file image descriptor (what peavine did)
– the clipboard contain the image contents (what Fredrik71, Shane and me did)
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "CoreImage"
set pathToPng to ((path to desktop as text) & "clippedimage.png") as «class furl»
try
clipboard info for {«class furl»}
set sourceFile to the clipboard as «class furl»
my fileFromFile:sourceFile toPath:pathToPng
on error
my fileFromClipToPath:pathToPng
end try
on fileFromClipToPath:thePath
set pb to current application's NSPasteboard's generalPasteboard() -- get pasteboard
set theData to pb's dataForType:(current application's NSPasteboardTypeTIFF) -- get tiff data off pasteboard
if theData = missing value then error "No tiff data found on clipboard"
set theCIImage to current application's CIImage's imageWithData:theData
my shared(theCIImage, thePath)
end fileFromClipToPath:
on shared(theCIImage, thePath)
-- grab the rectangle containing the image
set {{x, y}, {oldWidth, oldHeight}} to theCIImage's extent()
-- define the new size
set theWidth to 500 -- points
set theScale to theWidth / oldWidth
set theCIFilter to (current application's CIFilter's filterWithName:"CILanczosScaleTransform" withInputParameters:{inputScale:theScale, inputImage:theCIImage})
set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))
set theCIFilter to (current application's CIFilter's filterWithName:"CIColorControls" withInputParameters:{inputBrightness:0.15, inputImage:theCIImage}) -- change brightness to suit
set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))
set newRep to (current application's NSBitmapImageRep's alloc()'s initWithCIImage:theCIImage)
set theData to (newRep's representationUsingType:(current application's NSPNGFileType) |properties|:{NSImageInterlaced:false})
set theResult to (theData's writeToURL:thePath atomically:true)
end shared
on fileFromFile:imagePath toPath:thePath
set theImage to current application's NSImage's alloc()'s initWithContentsOfURL:imagePath -- load the file as an NSImage
set theData to theImage's TIFFRepresentation() -- get bitmap as data
set theCIImage to current application's CIImage's imageWithData:theData
my shared(theCIImage, thePath)
end fileFromFile:toPath:
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 27 janvier 2020 18:38:19
What Fredrik71 described in post #4 is exactly what I’m doing manually and that is the process I would like to automate. Using Preview to create the file from the clipboard and then manually adjusting the image.
I tried running the last script provided and it worked great. Thanks for all your help!
A question that remains unanswered for me is whether basic AppleScript can be used to save an image on the clipboard as a file. Preview does this but, as the OP notes, it’s convenient to automate this process.
After some Google research I found a procedure which I’ve modified as follows:
try
set theImage to the clipboard as GIF picture
on error
display dialog "Image not found on clipboard." buttons "OK" cancel button 1 default button 1
end try
set theFile to ((path to desktop) as text) & "Saved Image.gif"
try
set openedFile to open for access theFile with write permission
write theImage to openedFile
close access openedFile
on error
try
close access openedFile
end try
end try
This is the start of a slightly more direct approach:
set pb to current application's NSPasteboard's generalPasteboard() -- get pasteboard
set theTypes to pb's |types|()
if theTypes's containsObject:(current application's NSPasteboardTypeFileURL) then
set theURL to (pb's readObjectsForClasses:{current application's NSURL} options:{NSPasteboardURLReadingFileURLsOnlyKey:true})'s firstObject()
set theCIImage to current application's CIImage's imageWithContentsOfURL:theURL
else if theTypes's containsObject:(current application's NSPasteboardTypeTIFF) then
set theData to pb's dataForType:(current application's NSPasteboardTypeTIFF) -- get tiff data off pasteboard
set theCIImage to current application's CIImage's imageWithData:theData
else
error "Neither file nor image found on clipboard"
end if
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "CoreImage"
set thePath to ((path to desktop as text) & "clippedimage.png") as «class furl»
set pb to current application's NSPasteboard's generalPasteboard() -- get pasteboard
set theTypes to pb's |types|() -- the pipes are required with Script Debugger but will be removed by Script Editor!
if theTypes's containsObject:(current application's NSPasteboardTypeFileURL) then
set theURL to (pb's readObjectsForClasses:{current application's NSURL} options:{NSPasteboardURLReadingFileURLsOnlyKey:true})'s firstObject()
set theCIImage to current application's CIImage's imageWithContentsOfURL:theURL
else if theTypes's containsObject:(current application's NSPasteboardTypeTIFF) then
set theData to pb's dataForType:(current application's NSPasteboardTypeTIFF) -- get tiff data off pasteboard
set theCIImage to current application's CIImage's imageWithData:theData
else
error "Neither file nor image found on clipboard"
end if
set {{x, y}, {oldWidth, oldHeight}} to theCIImage's extent()
-- define the new size
set theWidth to 500 -- points
set theScale to theWidth / oldWidth
set theCIFilter to (current application's CIFilter's filterWithName:"CILanczosScaleTransform" withInputParameters:{inputScale:theScale, inputImage:theCIImage})
set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))
set theCIFilter to (current application's CIFilter's filterWithName:"CIColorControls" withInputParameters:{inputBrightness:0.15, inputImage:theCIImage}) -- change brightness to suit
set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))
set newRep to (current application's NSBitmapImageRep's alloc()'s initWithCIImage:theCIImage)
set theData to (newRep's representationUsingType:(current application's NSPNGFileType) |properties|:{NSImageInterlaced:false})
set theResult to (theData's writeToURL:thePath atomically:true)
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 28 janvier 2020 12:21:17