Reputation: 235
Trying to do something that I thought would be easy, and that is to get an online image's dimensions using javascript and then throwing those values back to AppleScript.
Check out this source code, I thought it would work, but I am a complete noob when it comes to Javascript.
set theVar to "https://i.ebayimg.com/images/g/M58AAMXQaBtRAPkA/s-l500.jpg"
set theScript to "var img = theVar;
var height = img.height;
var width = img.width;"
tell application "Safari"
do JavaScript theScript
end tell
set theResult to result
I would have hoped that the dimensions would have been returned as the result.
Upvotes: 1
Views: 599
Reputation: 3412
The files will need to be downloaded in order to get the images to work with, but you don't necessarily need to save them. You can use AppleScript or JXA to get the contents of the URL into an NSImage, where you can get its size
property - for example:
AppleScript:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
set theURL to current application's NSURL's URLWithString:"https://i.ebayimg.com/images/g/M58AAMXQaBtRAPkA/s-l500.jpg"
set theImage to current application's NSImage's alloc's initByReferencingURL:theURL
theImage's |size| as record
EDIT:
Taking another look after comments, if an URL is used that isn't an image, both script editors crash when using initWithContentsOfURL
(osascript
also errors out). Using initByReferencingURL
appears to work OK (you can also use the valid
property to check the image).
JXA:
ObjC.import('Cocoa')
theURL = $.NSURL.URLWithString('https://i.ebayimg.com/images/g/M58AAMXQaBtRAPkA/s-l500.jpg')
theImage = $.NSImage.alloc.initWithContentsOfURL(theURL)
theImage.size
Upvotes: 2
Reputation: 24982
Given that the URL in your question has one image consider the following gist:
set theURL to "https://i.ebayimg.com/images/g/M58AAMXQaBtRAPkA/s-l500.jpg"
set js to "[].slice.call(document.querySelectorAll('img')).map(function(img) {return {src: img.src, width: img.width, height: img.height}});"
tell application "Safari"
make new document with properties {URL:theURL}
delay 4
set imgProps to (do JavaScript js in current tab of window 1)
if (length of imgProps > 0) then
set {width:width} to item 1 of imgProps
set {height:height} to item 1 of imgProps
set {src:src} to item 1 of imgProps
log width
log height
log src
end if
end tell
Explanation:
The following line of JavaScript which is assigned to the AppleScript variable named js
:
[].slice.call(document.querySelectorAll('img')).map(function(img) {return {src: img.src, width: img.width, height: img.height}});
document
's querySelectorAll()
method to obtain a NodeList
of every img
element in the DOM.The [].slice.call(...)
part transforms the NodeList
(which are array-like) into an Array - this enables us to utilize methods provided by the Array such as map()
.
Note: For modern versions of Safari that support ecmascript-6 you can substitute this with the Array.from(...)
method. However, [].slice.call(...)
works for versions of Safari that support ES5 only, and modern ES6 too.
The callback function provided to map
, i.e. this part;
function(img) {return {src: img.src, width: img.width, height: img.height}}
return
s an Object with properties/values for src
, width
, and height
for each img
element.
The make new document with properties {URL:theURL}
part creates a new document in Safari with given URL. It essentially opens/loads the URL.
The delay 4
part utilizes the delay
command to pause script execution, (4 seconds in this example), to allow the webpage time to load before proceeding to execute the JavaScript.
Important You may need to increase/decrease this duration depending on how fast the page loads. There are also other solutions for waiting for the webpage to load that you may want to consider trying, such as this post, and this post. In essence Safari's AppleScript API doesn't provide a built-in feature for this so any solution, including the use of the delay
command, is a workaround/hack ¯\_(ツ)_/¯
The set imgProps to do JavaScript js in current tab of window 1
part executes the JavaScript and assigns the result (i.e. an AppleScript list of record's'), to the imgProps
variable.
The final parts:
set {width:width} to item 1 of imgProps
set {height:height} to item 1 of imgProps
set {src:src} to item 1 of imgProps
log width
log height
log src
assigns the values for each property (width
, height
, and src
) from the first record
in the list
to their own variables namely; width
, height
, and src
.
Finally, we log the value for each variable.
Note These final parts reside in the body of the if (length of imgProps > 0) then
staement so that they only run when the given webpage does contain one or more images
The same Javascript code as per above can be utilized to obtain the properties of all img
elements in a webpage. The notable difference in the following example are:
img
element.delay
duration is increased (note: change this as necessary).repeat
is utilized to loop through each record
in the list
and log
the properties.set theURL to "https://en.wikipedia.org/wiki/Car"
set js to "[].slice.call(document.querySelectorAll('img')).map(function(img) {return {src: img.src, width: img.width, height: img.height}});"
tell application "Safari"
make new document with properties {URL:theURL}
delay 8
set imgProps to do JavaScript js in current tab of window 1
if (length of imgProps > 0) then
repeat with img in items of imgProps
log width of img
log height of img
log src of img
log "-------"
end repeat
end if
end tell
Upvotes: 2
Reputation: 5
You could try a hacky method:
set theURL to "https://i.ebayimg.com/images/g/M58AAMXQaBtRAPkA/s-l500.jpg"
tell application "Safari"
set URL of document 1 to theURL
delay 1 --> lazy way to let image load; also see below
tell window 1
tell tab 1
do JavaScript ("window.location.reload();") -- refresh window; otherwise you might get "Untitled"
end tell
end tell
return name of document 1 --> "s-l500.jpg 500×301 pixels" -- from here you can parse to get dimensions
end tell
Upvotes: 0
Reputation: 3142
This is not a JavaScript solution. However, this following AppleScript code, will download all of the images from the image URLs you define in line 1 of the code. Next, it will write to a file, the image name and its dimensions. The end of the code provides a command to delete the downloaded images and will reveal the text file, in Finder, containing the image names and their dimensions.
The folder and file paths are not hardcoded, so all you need to do is enter the image URLs to the variable in the first line of this AppleScript.
This AppleScript code works for me using the latest version of macOS Mojave.
set imageURL to {"https://i.ebayimg.com/images/g/M58AAMXQaBtRAPkA/s-l500.jpg", "https://i.imgur.com/gQQHPBn.png"} -- Can Enter Multiples
-- Downloads The Images (Defined Above) To The Folder (Defined Below)
set downloadedImagesFolder to ((path to downloads folder as text) & "Images For Dimensions") as text
set quotedFormOfDownloadedImagesFolder to quoted form of POSIX path of downloadedImagesFolder
-- Writes Name Of Image And It's Dimensions To The File (Defined Below)
set imageDimensionsFile to ((path to downloads folder as text) & "File_Dimensions.txt") as text
set quotedFormOfImageDimensionsFile to quoted form of POSIX path of imageDimensionsFile
tell application "Finder"
if not (exists of folder downloadedImagesFolder) then
make new folder at (path to downloads folder) ¬
with properties {name:"Images For Dimensions"}
end if
end tell
repeat with i in imageURL
set imageURLText to i
set text item delimiters to "https" -- shell script "lwp-download " errors with "https"
set tempURL to text items of imageURLText
set text item delimiters to "http" -- replaces "https" with "http"
set finalImgeURL to tempURL as text
set text item delimiters to ""
try
do shell script "lwp-download " & quoted form of finalImgeURL & " " & quotedFormOfDownloadedImagesFolder
end try
end repeat
tell application "Finder"
set imageFiles to files of folder downloadedImagesFolder as alias list
set quotedFormOfImageFiles to {}
repeat with i in imageFiles
set end of quotedFormOfImageFiles to quoted form of POSIX path of i
end repeat
end tell
repeat with thisItem in quotedFormOfImageFiles
delay 2 -- May Need To Increase Value If Returning Null Value Results
-- replace " >> " with " > " Below... If You Prefer To Overwrite The File Instead Of Append
do shell script "mdls -name kMDItemFSName -name kMDItemPixelHeight -name kMDItemPixelWidth " & thisItem & " >> " & quotedFormOfImageDimensionsFile
end repeat
tell application "Finder" to reveal imageDimensionsFile
(* Comment Out Or Remove The Following Line If You Don't Want To
Delete The Downloaded Images *)
tell application "Finder" to delete folder downloadedImagesFolder
Upvotes: 1