I recently upgraded from Mojave to Big Sur, and am having trouble with a script that used to work just fine. The script, saved as a Cocoa-Applescript Applet app called “Display Image.app”, involves displaying an image:
use framework "Foundation"
use framework "AppKit"
use scripting additions
property dialogWindow : missing value -- the window
property dialogImageView : missing value -- the view
on run
set tid to AppleScript's text item delimiters
set {imagePathList, dimensionList} to {{}, {}}
set screenFrame to current application's class "NSScreen"'s mainScreen()'s frame()
if (screenFrame's class is record) then
set screenHeight to screenFrame's |size|'s height as integer
set screenWidth to screenFrame's |size|'s width as integer
else if (screenFrame's class is list) then
set screenHeight to (item 2 of item 2 of screenFrame) as integer
set screenWidth to (item 1 of item 2 of screenFrame) as integer
end if
set imagetext to the clipboard
set orientPic to "Horizontal"
set AppleScript's text item delimiters to return
set imagePathListText to text item 1 of imagetext as string
set imageNameListText to text item 2 of imagetext as string
set imageXY to text item 3 of imagetext as string
try
set imageRatio to text item 4 of imagetext as number
end try
try
set orientPic to text item 5 of imagetext as string
end try
set windowWidth to (screenWidth / imageRatio)
set windowHeight to ((screenHeight - 48) / imageRatio)
set AppleScript's text item delimiters to ASCII character 9
set imageCount to count of text items of imagePathListText
if orientPic = "Horizontal" then
set targetImageWidth to ((windowWidth - 2) - (imageCount * 2)) / imageCount
else if orientPic = "Vertical" then
set targetImageHeight to ((windowHeight - 2) - (imageCount * 20)) / imageCount
else
set imageCountSQRT to imageCount ^ 0.5
set imageColumnCount to round imageCountSQRT rounding up
if imageColumnCount = imageCountSQRT then
set imageRowCount to imageColumnCount
else
set imageRowCount to ((imageCount - 1) div imageColumnCount) + 1
end if
set targetImageWidth to ((windowWidth - 2) - (imageRowCount * 2)) / imageRowCount
set targetImageHeight to ((windowHeight - 2) - (imageColumnCount * 20)) / imageColumnCount
end if
set {newImageList, newNameList} to {{}, {}}
set {maxImageWidth, maxImageHeight} to {0, 0}
repeat with i from 1 to imageCount
set imagePath to text item i of imagePathListText as string
set imageName to text item i of imageNameListText as string
set AppleScript's text item delimiters to tid
--try
set imageHeight to do shell script "mdls -name kMDItemPixelHeight -raw -nullMarker 0 " & quoted form of (POSIX path of imagePath)
set imageHeight to imageHeight as number
set imageWidth to do shell script "mdls -name kMDItemPixelWidth -raw -nullMarker 0 " & quoted form of (POSIX path of imagePath)
set imageWidth to imageWidth as number
if orientPic contains "Horizontal" then
if (imageHeight > (windowHeight - 4)) or (imageWidth > targetImageWidth) then
repeat while (imageHeight > (windowHeight - 4)) or (imageWidth > targetImageWidth)
if imageWidth > targetImageWidth then
set imageScaler to targetImageWidth / imageWidth
set imageHeight to imageHeight * imageScaler
set imageWidth to targetImageWidth
end if
if imageHeight > (windowHeight - 4) then
set imageScaler to (windowHeight - 4) / imageHeight
set imageWidth to imageWidth * imageScaler
set imageHeight to windowHeight - 4
end if
end repeat
end if
end if
if orientPic contains "Vertical" then
if (imageWidth > (windowWidth - 4)) or (imageHeight > targetImageHeight) then
repeat while (imageWidth > (windowWidth - 4)) or (imageHeight > targetImageHeight)
if imageHeight > targetImageHeight then
set imageScaler to targetImageHeight / imageHeight
set imageWidth to imageWidth * imageScaler
set imageHeight to targetImageHeight
end if
if imageWidth > (windowWidth - 4) then
set imageScaler to (windowWidth - 4) / imageWidth
set imageHeight to imageHeight * imageScaler
set imageWidth to windowWidth - 4
end if
end repeat
end if
end if
set imageSize to {imageWidth, imageHeight}
copy imageSize to end of dimensionList
if imageHeight > maxImageHeight then set maxImageHeight to imageHeight
if imageWidth > maxImageWidth then set maxImageWidth to imageWidth
if orientPic contains "Horizontal" then
if maxImageWidth > targetImageWidth then set maxImageWidth to targetImageWidth
end if
if orientPic contains "Vertical" then
if maxImageHeight > targetImageHeight then set maxImageHeight to targetImageHeight
end if
copy imagePath to end of newImageList
copy imageName to end of newNameList
--end try
set AppleScript's text item delimiters to ASCII character 9
end repeat
set AppleScript's text item delimiters to tid
if newImageList = {} then
activate
display dialog "There are no viable images to display." giving up after 1
return
else
set imageCount to (count of newImageList)
set imageColumnCount to imageCount
if orientPic = "HorizontalVertical" then
set imageCountSQRT to imageCount ^ 0.5
set imageColumnCount to round imageCountSQRT rounding up
if imageColumnCount = imageCountSQRT then
set imageRowCount to imageColumnCount
else
set imageRowCount to ((imageCount - 1) div imageColumnCount) + 1
end if
set imageCount to imageColumnCount
end if
if orientPic contains "Horizontal" then
set maxWindowWidth to (maxImageWidth * imageColumnCount) + ((imageColumnCount - 1) * 2) + 4
if windowWidth > maxWindowWidth then set windowWidth to maxWindowWidth
if orientPic = "Horizontal" then
if windowHeight > ((maxImageHeight + 2) * imageColumnCount) + 2 then set windowHeight to ((maxImageHeight + 2) * imageColumnCount) + 2
if windowHeight > maxImageHeight + 4 then set windowHeight to maxImageHeight + 4
else
if windowHeight > ((maxImageHeight + 20) * imageRowCount) + 2 then set windowHeight to ((maxImageHeight + 20) * imageRowCount) + 2
end if
end if
if orientPic = "Vertical" then
set maxWindowHeight to ((maxImageHeight + 20) * imageColumnCount) + 4
if windowHeight > maxWindowHeight then set windowHeight to maxWindowHeight
if windowWidth > maxImageWidth + 4 then set windowWidth to maxImageWidth + 4
end if
set {imageX, imageY} to {character 1, character 2} of imageXY
if imageX = "L" then
set windowX to 0
else if imageX = "C" then
set windowX to (screenWidth - (windowWidth + 2)) / 2
else if imageX = "R" then
set windowX to screenWidth - (windowWidth + 2)
end if
if imageY = "B" then
set windowY to 0
else if imageY = "M" then
set windowY to ((screenHeight - 22) - (windowHeight + 2)) / 2
else if imageY = "T" then
set windowY to screenHeight - 24
end if
# create the window
set dialogWindow to current application's NSWindow's alloc's initWithContentRect:{{windowX, windowY}, {windowWidth, windowHeight + 40}} styleMask:7 backing:(current application's NSBackingStoreBuffered) defer:true -- mask of 7 = title, close, minimize
tell dialogWindow -- set some window properties
setPreventsApplicationTerminationWhenModal_(false)
setAllowsConcurrentViewDrawing_(true)
setReleasedWhenClosed_(false)
setLevel_(current application's NSNormalWindowLevel)
setHasShadow_(true)
setTitle_("Display Image")
set imageCount to count of newImageList
set {maxHeight, maxWidth} to {0, 0}
repeat with i from 1 to imageCount
# create image view
set imagePath to item i of newImageList as string
set imageName to item i of newNameList as string
set theImage to (current application's NSImage's alloc()'s initWithContentsOfFile:(POSIX path of imagePath))
set {imageWidth, imageHeight} to item i of dimensionList
if orientPic contains "Horizontal" then
if (imageHeight > windowHeight - 4) or (imageWidth > targetImageWidth) then
repeat while (imageHeight > windowHeight - 4) or (imageWidth > targetImageWidth)
if imageWidth > targetImageWidth then
set imageScaler to targetImageWidth / imageWidth
set imageHeight to imageHeight * imageScaler
set imageWidth to targetImageWidth
end if
if imageHeight > (windowHeight - 4) then
set imageScaler to (windowHeight - 4) / imageHeight
set imageWidth to imageWidth * imageScaler
set imageHeight to windowHeight - 4
end if
end repeat
end if
end if
if orientPic contains "Vertical" then
if (imageWidth > windowWidth - 4) or (imageHeight > targetImageHeight) then
repeat while (imageWidth > windowWidth - 4) or (imageHeight > targetImageHeight)
if imageHeight > targetImageHeight then
set imageScaler to targetImageHeight / imageHeight
set imageWidth to imageWidth * imageScaler
set imageHeight to targetImageHeight
end if
if imageWidth > (windowWidth - 4) then
set imageScaler to (windowWidth - 4) / imageWidth
set imageHeight to imageHeight * imageScaler
set imageWidth to windowWidth - 4
end if
end repeat
end if
end if
if imageWidth > maxWidth then set maxWidth to imageWidth
if imageHeight > maxHeight then set maxHeight to imageHeight
if orientPic = "Horizontal" then
set imageLeft to ((i - 1) * (maxWidth + 2)) + 2
set imageBottom to 2
else
set imageNum to imageCount - i + 1
if orientPic = "Vertical" then
set imageBottom to ((imageNum - 1) * (maxHeight + 20)) + 2
set imageLeft to 2
else
set imageNum to imageCount - i + 1
if imageCount mod imageRowCount = 0 then
set imageXNumber to imageColumnCount - ((imageNum - 1) mod imageColumnCount) - 1
set imageYNumber to ((imageNum - 1) div imageColumnCount)
else
set imageXNumber to imageColumnCount - (imageNum mod imageColumnCount) - 1
set imageYNumber to (imageNum div imageColumnCount)
end if
set imageLeft to (imageXNumber * maxWidth) + ((imageXNumber + 1) * 2)
set imageBottom to (imageYNumber * (maxHeight + 20)) + ((imageYNumber + 1) * 2)
end if
end if
set dialogImageView to (current application's NSImageView's alloc's initWithFrame:{{imageLeft, imageBottom}, {imageWidth, imageHeight}})
tell theImage to setSize:{imageWidth, imageHeight}
(dialogImageView's setImage:theImage)
its (contentView's addSubview:dialogImageView) -- add the view
set text_field to current application's NSTextField's new
if orientPic = "Horizontal" then
set {textLeft, textBottom, textWidth, textHeight} to {imageLeft, imageBottom + maxHeight, maxWidth, 40}
else
set {textLeft, textBottom, textWidth, textHeight} to {imageLeft, imageBottom + maxHeight, maxWidth, 20}
end if
set text_field to (current application's NSTextField's alloc's initWithFrame:{{textLeft, textBottom}, {textWidth, textHeight}})
(text_field's setEditable:false)
(text_field's setBezeled:false)
(text_field's setDrawsBackground:false)
(text_field's setStringValue:imageName)
its (contentView's addSubview:text_field) -- add the view
end repeat
end tell
tell dialogWindow to setFrameOrigin:{windowX, windowY}
tell dialogWindow to makeKeyAndOrderFront:me -- show the window
end if
end run
The problematic part of the script involves getting the dimensions of the image:
set imageHeight to do shell script "mdls -name kMDItemPixelHeight -raw -nullMarker 0 " & quoted form of (POSIX path of imagePath)
set imageHeight to imageHeight as number
set imageWidth to do shell script "mdls -name kMDItemPixelWidth -raw -nullMarker 0 " & quoted form of (POSIX path of imagePath)
set imageWidth to imageWidth as number
Whenever I try to use this on a file that is not on my startup disk, I get a message like this when it gets to that part of the script:
“An error occurred while running
/Volumes/External/File.jpg: could not find /Volumes/External/File.jpg. (1)”
I don’t get that error message if I use that part of the script by itself.
The script is called from another script:
set pathList to choose file of type {"jpg"}
set pathList to pathList as string
set nameList to "Whatever"
set appName to "Finder"
displayImage(pathList, nameList, appName)
on displayImage(pathList, nameList, appName)
try
tell application "Display Image" to quit
end try
set imageFolder to path to desktop as string
set picOrient to "Vertical"
set pathListList to text2List(pathList, ASCII character 9)
if (count of pathListList) = 1 then
set {picOrient, imageRatio} to {"Horizontal", 3}
else if (count of pathListList) = 2 then
set {picOrient, imageRatio} to {"Vertical", 2}
else
set {picOrient, imageRatio} to {"HorizontalVertical", 2}
end if
set the clipboard to pathList & return & nameList & return & "RT" & return & imageRatio & return & picOrient
tell application "Display Image"
launch
activate
end tell
if appName ≠ "" then
try
tell application appName to activate
end try
end if
end displayImage
on text2List(theText, textDelim)
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to textDelim
set textList to text items of theText
set AppleScript's text item delimiters to tid
return textList
end text2List
I have rebuilt the Spotlight index on the drive to no avail. Any suggestions would be appreciated. Thanks.
Model: Mac Mini 2018
AppleScript: 2.11
Browser: Safari 605.1.15
Operating System: Other