Exporting folder contents, PDFs or images to jpg

Below is a version offering new handlers.
When it treat picture files it just change the dimensions, no longer adjust the compression factor.
For PDFs, it apply the filter “CILanczosScaleTransform” which is supposed to give better results when it apply a resolution greater than the standard 72.

use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "Quartz"
use framework "QuartzCore"
use framework "CoreImage"

-- Yvan KOENIG (VALLAURIS, France) 16 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}
	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
			set maxDim to 0 -- Give a non null value if you want to resize the jpegs
			if typeID is in {"public.png", "public.tiff"} then
				-- Define compressionFactor in the range : 0.2 ≤ compressionFactor ≤ 1.0
				(my resizedJpegFromPath:aPOSIXPath maxHeightOrWidth:maxDim compressionFactor:0.8)
				delete disk item aFile
			else if typeID is "public.jpeg" and maxDim ≠ 0 then
				-- Define compressionFactor in the range : 0.2 ≤ compressionFactor ≤ 1.0
				-- With the parameters defined below, it's better to skip resizing process
				(my resizedJpegFromPath:aPOSIXPath maxHeightOrWidth:maxDim compressionFactor:0.8)
				delete disk item aFile
			else if typeID is "com.adobe.pdf" then
				(my treatPDF:aPOSIXPath) -- Don't resize the jpegs
				delete disk item aFile
			end if
		end repeat
	end tell -- System Events
end open

#=====

-- handler used for picture files

on resizedJpegFromPath:imagePath maxHeightOrWidth:maxDim compressionFactor:compFactor
	-- 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 maxDim = 0 then -- don't change the dimensions
		set theWidth to oldWidth
		set theHeight to oldHeight
	else
		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
	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 theData to newRep's representationUsingType:(current application's NSJPEGFileType) |properties|:{NSImageCompressionFactor:compFactor}
	
	theData's writeToFile:outPath atomically:true
end resizedJpegFromPath:maxHeightOrWidth:compressionFactor:

#=====

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 converted into jpeg ones
	set fileManager to (a reference to current application's NSFileManager's defaultManager()) -- do that only once
	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 to convert tiff into jpeg
		-- apply the wanted resolution
		(my resizedJpegFromPath:outPath newRes:200) -- Edit newRes to fit your needs
		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 -- imagePath is a POSIX Path of a Tiff file
	-- handler from Shane Stanley, edited by Yvan Koenig
	set compFactor to 1 -- Edit to fit your needs. Allowed range 0 < compFactor ≤ 1
	set theURL to current application's NSURL's fileURLWithPath:imagePath
	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"
	set theCIImage to current application's CIImage's imageWithContentsOfURL:theURL
	if theRes ≠ 72 then
		set theScale to theRes / 72
		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.0, inputImage:theCIImage}) -- change brightness if you want (0.0 ≤ brightness ≤ 0.15)
		--set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))
	end if
	set newRep to (current application's NSBitmapImageRep's alloc()'s initWithCIImage:theCIImage)
	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 thePathNoExt to pathString's stringByDeletingPathExtension()
	set newPath to (thePathNoExt's stringByAppendingString:extraString)'s stringByAppendingPathExtension:aExt
	return newPath as string
end addString:beforeExtensionIn:addingExtension:

#=====

Now you are free to use the handlers of your choice.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 16 juin 2020 12:20:02

Yvan you are amazing!!! It is perfect now!

Thank you so much for all of the work you put into this!

Your dedication and commitment is unparalleled.

Amazing job! I have no words of how to THANK YOU!!!