通过 AppleScript 使用 Javascript 获取图像尺寸

Getting image dimensions using Javascript via AppleScript

尝试做一些我认为很容易的事情,那就是使用 javascript 获取在线图像的尺寸,然后将这些值传回 AppleScript。

查看此源代码,我认为它可以工作,但我是一个完整的菜鸟 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

我希望尺寸会作为结果返回。

您可以尝试一个 hacky 方法:

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

这不是 JavaScript 解决方案。但是,以下 AppleScript 代码将从您在代码第 1 行中定义的图像 URL 下载所有图像。接下来,它会将图像名称及其尺寸写入文件。代码末尾提供了删除下载图像的命令,并将在 Finder 中显示包含图像名称及其尺寸的文本文件。

文件夹和文件路径不是硬编码的,因此您需要做的就是在此 AppleScript 的第一行中将图像 URL 输入变量。

此 AppleScript 代码适用于使用最新版本的 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

需要下载文件才能使用图像,但您不一定需要保存它们。您可以使用 AppleScriptJXA 将 URL 的内容放入 NSImage ,在那里你可以得到它的 size 属性 - 例如:

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

编辑:

再看看评论,如果使用 URL 而 不是 图像,两个脚本编辑器在使用 initWithContentsOfURL 时都会崩溃(osascript 也出错)。使用 initByReferencingURL 似乎工作正常(您也可以使用 valid 属性 检查图像)。

JXA:

ObjC.import('Cocoa')
theURL = $.NSURL.URLWithString('https://i.ebayimg.com/images/g/M58AAMXQaBtRAPkA/s-l500.jpg')
theImage = $.NSImage.alloc.initWithContentsOfURL(theURL)
theImage.size

获取第一张图片的宽高属性:

鉴于您问题中的 URL 只有一张图片,请考虑以下要点:

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

解释:

  1. JavaScript 的下一行分配给名为 js 的 AppleScript 变量:

    [].slice.call(document.querySelectorAll('img')).map(function(img) {return {src: img.src, width: img.width, height: img.height}});
    
    • 利用documentquerySelectorAll()方法获取DOM中每个img元素的NodeList
    • [].slice.call(...) 部分将 NodeList(即 array-like)转换为数组 - 这使我们能够利用 Array 提供的方法,例如 map().

      注意: 对于支持 you can substitute this with the Array.from(...) 方法的现代版本的 Safari。但是,[].slice.call(...) 适用于仅支持 ES5 和现代 ES6 的 Safari 版本。

    • 提供给map的回调函数,即这部分;

      function(img) {return {src: img.src, width: img.width, height: img.height}}
      

      returns 一个对象,srcwidth 为 properties/values,每个 img 元素为 height

  2. make new document with properties {URL:theURL} 部分使用给定的 URL 在 Safari 中创建一个新文档。它本质上是 opens/loads URL.

  3. delay 4 部分利用 delay 命令暂停脚本执行(本例中为 4 秒),以便在继续执行之前让网页有时间加载JavaScript.

    重要您可能需要 increase/decrease 此持续时间,具体取决于页面加载的速度。还有其他等待网页加载的解决方案您可能想考虑尝试,例如 this post, and this post。本质上,Safari 的 AppleScript API 没有为此提供 built-in 功能,因此任何解决方案,包括 delay 命令的使用,都是 workaround/hack ¯\_(ツ)_/¯

  4. set imgProps to do JavaScript js in current tab of window 1 部分执行 JavaScript 并将结果(即 AppleScript list of record's')分配给 imgProps变量.

  5. 最后部分:

    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
    

    list 中第一个 record 中的每个 属性(widthheightsrc)赋值即他们自己的变量; widthheightsrc

    最后,我们记录每个变量的值。

    注意 这些最终部分位于 if (length of imgProps > 0) then 状态的主体中,因此它们仅在给定网页执行时 运行包含一张或多张图片


获取所有图片的宽高属性:

与上述相同的 Javascript 代码可用于获取网页中所有 img 元素的属性。以下示例中的显着差异是:

  1. 提供了一个不同于 URL 的网页,其中包含多个 img 元素。
  2. delay 持续时间增加 (注意:根据需要更改)
  3. repeat用于遍历listlog属性中的每个record
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