I repeat : you don’t have to use the folder Ymages.
The run handler was only created for tests.
The script is supposed to be saved as an application upon which you drag and drop items to treat.
Your original message stated :
I want to create a script that takes as input folders/files and outputs them as jpg images in a different folder and at a lower resolution.
So my script was written to do that but, as you never described what is the wanted lower resolution I delivered a script allowing you to rule it.
It’s why an the dedicated instruction was carefully commented :
my resizedJpegFromPath:aPOSIXPath maxHeightOrWidth:800 targetBytes:100000 – Edit to fit your needs
In a recent message I told you that you may change the parameter maxHeightOrWidth and/or the parameter targetBytes. I even suggested that you may set this one to 100000 * 100 to get better quality.
For the PDFs if I asked it’s because, as I already wrote, exporting a PDF as Jpeg, default to 200 pixels/inch. As I never used this function I didn’t knew that it may default to an other resolution.
I’m tired to waste time for a user which doesn’t take care of what is carefully answered.
Below is a version allowing you to set the parameter according to your needs and now, for me : GAME OVER.
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "Quartz"
use framework "QuartzCore"
-- Yvan KOENIG (VALLAURIS, France) 13 juin 2020 12:20:33
(*
on run -- useful ONLY for tests, I repeat : useful ONLY for tests
set p2d to path to desktop as string
set draggeditems to {(p2d & "2018-10-07 Walter notes 1.pdf") as alias, (p2d & "Ymages:") as alias, (p2d & "Ymages copie:") as alias}
--set draggeditems to {(p2d & "Ymages:") as alias}
open draggeditems
end run
*)
on open draggeditems
set p2d to path to desktop as string
tell application "System Events"
set nbFolders to 0
set nbFiles to 0
repeat with anItem in draggeditems
if (type identifier of anItem) is "public.folder" then
set nbFolders to nbFolders + 1
else
set nbFiles to nbFiles + 1
end if
end repeat
if (nbFolders = 1) and nbFiles = 0 then
set storageName to (name of anItem) & "_Resized"
if exists disk item storageName of folder p2d then
-- build a new name so we will not duplicate
set storageName to storageName & my buildStamp()
end if
else
set storageName to "Resized_Folder"
if exists disk item storageName of folder p2d then
-- build a new name so we will not duplicate
set storageName to storageName & my buildStamp()
end if
end if
set storagePath to p2d & storageName -- is an Hfs path
make new folder at end of folder p2d with properties {name:storageName}
-- Now we have an empty folder to work with
repeat with anItem in draggeditems
set typeID to type identifier of anItem
if typeID is "public.folder" then -- It's a folder, duplicate every embedded file into the storage folder
set allFiles to (path of every file of anItem whose visible is true)
repeat with aFile in allFiles
(my duplicateFileAt:aFile toFolder:storagePath) -- here, aFile is an alias and storagePath is an Hfs path
end repeat
else -- here we have a file, duplicate it into the storage folder
if typeID is in {"public.png", "public.jpeg", "public.tiff", "com.adobe.pdf"} then
(my duplicateFileAt:anItem toFolder:storagePath) -- here, anItem is an alias and storagePath is an Hfs path
end if
end if
end repeat
-- we would have build a list before
-- but I choose this scheme because adding items to an Applescript list is slow
set allFiles to (path of every file of folder storagePath whose visible is true)
repeat with aFile in allFiles
set aPOSIXPath to (my makePOSIXPath:aFile)
set typeID to get type identifier of file aFile
if typeID is in {"public.png", "public.jpeg", "public.tiff"} then
--(my treatPicture:aPOSIXPath) -- don't change that
(my resizedJpegFromPath:aPOSIXPath maxHeightOrWidth:800 targetBytes:100000 * 100) -- Edit to fit your needs
else if typeID is "com.adobe.pdf" then
(my treatPDF:aPOSIXPath)
end if
delete disk item aFile
end repeat
end tell -- System Events
end open
#=====
-- handler used for picture files
on resizedJpegFromPath:imagePath maxHeightOrWidth:maxDim targetBytes:maxBytes
-- handler from Shane Stanley
set imagePath to current application's NSString's stringWithString:imagePath
set outPath to (imagePath's stringByDeletingPathExtension()'s stringByAppendingString:"-out")
set outPath to outPath's stringByAppendingPathExtension:"jpg"
-- Get the contents of the passed picture
set theImageRep to current application's NSBitmapImageRep's imageRepWithContentsOfFile:imagePath -- load the file
set theClip to current application's NSPasteboard's generalPasteboard()
-- Extract its original size
set oldHeight to theImageRep's pixelsHigh()
set oldWidth to theImageRep's pixelsWide()
if oldWidth > oldHeight then
set theWidth to maxDim
set theHeight to oldHeight * maxDim / oldWidth
else
set theHeight to maxDim
set theWidth to oldWidth * maxDim / oldHeight
end if
set newRep to (current application's NSBitmapImageRep's alloc()'s initWithBitmapDataPlanes:(missing value) pixelsWide:theWidth pixelsHigh:theHeight bitsPerSample:8 samplesPerPixel:4 hasAlpha:yes isPlanar:false colorSpaceName:(current application's NSDeviceRGBColorSpace) bytesPerRow:0 bitsPerPixel:32)
-- store the existing graphics context
current application's NSGraphicsContext's saveGraphicsState()
-- set graphics context to new context based on the new bitmapImageRep
current application's NSGraphicsContext's setCurrentContext:(current application's NSGraphicsContext's graphicsContextWithBitmapImageRep:newRep)
theImageRep'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 respectFlipped:false hints:(missing value)
-- restore state
current application's NSGraphicsContext's restoreGraphicsState()
set compFactor to 0.8 -- starting compression value
set compMax to 0.2 -- compression limit
repeat
set theData to newRep's representationUsingType:(current application's NSJPEGFileType) |properties|:{NSImageCompressionFactor:compFactor}
if compFactor > compMax and theData's |length|() > maxBytes then
-- too big, so try with more compression
set compFactor to compFactor * 0.9
else -- give up
exit repeat
end if
end repeat
theData's writeToFile:outPath atomically:true
end resizedJpegFromPath:maxHeightOrWidth:targetBytes:
#=====
on buildStamp()
tell (current date) to return "_" & (((its year) * 10000 + (its month) * 100 + (its day)) as string) & "_" & text 2 thru -1 of ((1000000 + (its hours) * 10000 + (its minutes) * 100 + (its seconds)) as string)
end buildStamp
#=====
on makePOSIXPath:aFile
return POSIX path of aFile
end makePOSIXPath:
#=====
on duplicateFileAt:sourcePath toFolder:destFolder -- here, sourcePath is an alias and destFolder is an Hfs path
set POSIXsource to current application's NSString's stringWithString:(POSIX path of sourcePath)
set POSIXdest to current application's NSString's stringWithString:(POSIX path of destFolder)
set theNewPath to POSIXdest's stringByAppendingPathComponent:(POSIXsource's lastPathComponent())
set fileManager to current application's NSFileManager's defaultManager()
if fileManager's fileExistsAtPath:theNewPath then
set thePathNoExt to theNewPath's stringByDeletingPathExtension()
set stamp to my buildStamp()
set theExtension to POSIXsource's pathExtension()
-- insert the stamp in the file name so it will not duplicate
set theNewPath to (thePathNoExt's stringByAppendingString:stamp)'s stringByAppendingPathExtension:theExtension
end if
set {theResult, theError} to fileManager's copyItemAtPath:POSIXsource toPath:theNewPath |error|:(reference)
if (theResult as boolean) is false then
error (theError's localizedDescription() as string)
end if
end duplicateFileAt:toFolder:
#=====
on treatPDF:aPOSIXPath
-- code from Takaaki Naganoya
-- set aPOSIXpath to POSIX path of aFile
set aURL to (current application's |NSURL|'s fileURLWithPath:aPOSIXPath)
set aPDFdoc to current application's PDFDocument's alloc()'s initWithURL:aURL
set pCount to aPDFdoc's pageCount()
-- Split the PDF into pages exported as Tiff files
repeat with i from 0 to (pCount - 1)
set thisPage to (aPDFdoc's pageAtIndex:(i))
set thisDoc to (current application's NSImage's alloc()'s initWithData:(thisPage's dataRepresentation()))
if thisDoc = missing value then error "Error in getting imagerep from PDF in page:" & (i as string)
set theData to thisDoc's TIFFRepresentation()
set newRep to (current application's NSBitmapImageRep's imageRepWithData:theData)
set targData to (newRep's representationUsingType:(current application's NSTIFFFileType) |properties|:{NSTIFFCompressionNone:1})
set ztext to text -4 thru -1 of ((10001 + i) as string)
set outPath to (my addString:("_" & ztext) beforeExtensionIn:aPOSIXPath addingExtension:"tiff")
(targData's writeToFile:outPath atomically:true) -- Export
-- added instructions
-- apply the wanted reduction
(my resizedJpegFromPath:outPath newRes:200) -- Edit the newRes to fit your needs
set fileManager to (a reference to current application's NSFileManager's defaultManager())
set tiffURL to (current application's |NSURL|'s fileURLWithPath:outPath)
(fileManager's removeItemAtURL:tiffURL |error|:(missing value))
end repeat
end treatPDF:
#=====
-- Handler used for splitted PDFs
on resizedJpegFromPath:imagePath newRes:theRes
-- handler from Shane Stanley, edited by Yvan Koenig
set imagePath to current application's NSString's stringWithString:imagePath
set outPath to (imagePath's stringByDeletingPathExtension()'s stringByAppendingString:"-out")
set outPath to outPath's stringByAppendingPathExtension:"jpg"
-- Get the contents of the passed picture
set theImageRep to current application's NSBitmapImageRep's imageRepWithContentsOfFile:imagePath -- load the file
set theClip to current application's NSPasteboard's generalPasteboard()
-- Extract its original size
set oldHeight to theImageRep's pixelsHigh()
set oldWidth to theImageRep's pixelsWide()
-- Calculate new size according to, wanted resolution
set theWidth to oldWidth * theRes / 72
set theHeight to oldHeight * theRes / 72
set newRep to (current application's NSBitmapImageRep's alloc()'s initWithBitmapDataPlanes:(missing value) pixelsWide:theWidth pixelsHigh:theHeight bitsPerSample:8 samplesPerPixel:4 hasAlpha:yes isPlanar:false colorSpaceName:(current application's NSDeviceRGBColorSpace) bytesPerRow:0 bitsPerPixel:32)
-- store the existing graphics context
current application's NSGraphicsContext's saveGraphicsState()
-- set graphics context to new context based on the new bitmapImageRep
current application's NSGraphicsContext's setCurrentContext:(current application's NSGraphicsContext's graphicsContextWithBitmapImageRep:newRep)
theImageRep'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 respectFlipped:false hints:(missing value)
-- restore state
current application's NSGraphicsContext's restoreGraphicsState()
set compFactor to 1 -- Edit to fit your needs. Allowed range 0 < compFactor ≤ 1
set theData to newRep's representationUsingType:(current application's NSJPEGFileType) |properties|:{NSImageCompressionFactor:compFactor}
theData's writeToFile:outPath atomically:true
end resizedJpegFromPath:newRes:
#=====
-- Add an extra string and the name extension at the end of the POSIX path
on addString:extraString beforeExtensionIn:aPath addingExtension:aExt
set pathString to current application's NSString's stringWithString:aPath
--set theExtension to pathString's pathExtension()
set thePathNoExt to pathString's stringByDeletingPathExtension()
set newPath to (thePathNoExt's stringByAppendingString:extraString)'s stringByAppendingPathExtension:aExt
return newPath as string
end addString:beforeExtensionIn:addingExtension:
#=====
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) samedi 13 juin 2020 12:42:06