【问题标题】:AppleScript to convert NEF to JPG preserving Creation Date/TimeAppleScript 将 NEF 转换为 JPG 保留创建日期/时间
【发布时间】:2013-09-11 04:50:48
【问题描述】:

我有一台尼康相机,可以输出很好的 NEF 原始文件,而不是很好的 JPEG 文件。我可以使用 Mac OSX 10.6.8 (Snow Leopard) 附带的 Preview 应用程序来简单地打开 NEF 和 SaveAs JPEG 以创建一个大小约为 1/6 的文件,该文件与原始 NEF 几乎没有区别。

[编辑] 这是最终的脚本,可以按需要运行,带有 cmets 和一些错误测试:

(*
 AppleScript to convert Nikon raw NEF files into much smaller JPG files.
 The JPG files will inherit the file date and time of the source NEF files.
 Note that any JPG files in the target folder that have the same name
 as a NEF file in that folder, will be overwritten.
 *)

-- User selects target folder with NEF files to convert and save there. 
set theImageFolder to choose folder with prompt "
Select a folder containing fileⁿ.NEF images to 
convert into JPEG images and SaveAs: fileⁿ.JPG"
set theOutputFolder to theImageFolder

-- Finder locates NEF files, ignoring other file types in the target folder.
tell application "Finder"
    set theImages to every file of theImageFolder whose name extension is "NEF"
end tell

-- Image Events app processes the images.
tell application "Image Events"
    launch
    repeat with a from 1 to length of theImages

        -- Get file name as text string.
        set theImage to file ((item a of theImages) as string)

        -- Get date/time of source NEF file.
        tell application "Finder" to set fileTimestamp to creation date of theImage
        set theImageReference to open theImage
        tell theImageReference
            set theImageName to name

            -- Detect the .NEF extension to replace with .JPG on output.
            set savedDelimiters to AppleScript's text item delimiters

            -- Split filename string into list, using "." as a delimiter.
            set AppleScript's text item delimiters to {"."}
            set delimitedList to every text item of theImageName

            -- Remove the .NEF extension from the list, if it was there.
            ignoring case

                --Process only NEF files.
                if last item of delimitedList is "NEF" then
                    set filenameList to items 1 thru -2 of delimitedList
                    set theImageName to filenameList as string
                end if
            end ignoring

            -- Restore delimiters to default in case it had previously been changed.
            set AppleScript's text item delimiters to savedDelimiters

            -- Construct full path of file to save, with JPG as output file extension.
            set saveImageName to ((theOutputFolder as string) & theImageName & ".JPG")

            -- Check if a file with the output JPG file name is already present in the target folder.
            tell application "Finder"
                if exists file saveImageName then

                    -- Abort script if user doesn't want to overwrite this file and continue.
                    beep
                    if button returned of (display dialog "     An identical JPG file is already at:
" & saveImageName & "

     Would you like to:" buttons {"Replace it and continue", "Abort"} default button "Abort") is "Abort" then exit repeat
                end if
            end tell

            -- SaveAs the file in JPEG format, leaving the source NEF file unmodified.
            set saveImageName to save in saveImageName as JPEG

            --Match the output JPG file date/time to that of the NEF source file.
            tell application "Finder" to set modification date of saveImageName to fileTimestamp
        end tell
    end repeat
end tell
tell application "Finder"
    display alert "Done.  Duplicated selected NEF files in
  " & theOutputFolder & " 
as JPGs with dates/times matching NEFs."
end tell

以下是我最初尝试创建 AppleScript 以节省我在数百个 NEF 文件上使用 Preview 应用手动执行此操作所需的时间。它可以工作,但是这个网站上乐于助人的人帮助我大大改进了它。正如您从初始用户提示中看到的那样,我只想在现有 JPG 文件将被替换的情况下提示用户。我还希望输出文件名是 n.JPG 而不是 n.NEF.jpg 并让输出 JPG 文件继承原始 NEF 文件的创建日期和时间。我欢迎任何建议,但由于我已经走到这一步,我的偏好是避免添加 shell 脚本,并尽可能使用 AppleScript 来完成。

set theImageFolder to choose folder with prompt "Note:  This script will replace any existing files in the selected folder matching
the name of a NEF file and end in a JPG extension with a new file of that name.  
For example, X.NEF will create X.JPG and replace any existing file named X.JPG 
that was already in the selected folder (not in any other folders). To begin now,
Select a folder with NEF images to convert into JPEG images:"
set theOutputFolder to theImageFolder

tell application "Finder"
    set theImages to every file of theImageFolder whose name extension is "NEF"
end tell

tell application "Image Events"
    launch
    repeat with a from 1 to length of theImages
        set theImage to file ((item a of theImages) as string)
        set theImageReference to open theImage
        tell theImageReference
            set theImageName to name
            save in ((theOutputFolder as string) & theImageName & ".JPG") as JPEG
        end tell
    end repeat
end tell
tell application "Finder"
    display alert "Done.  All NEF files in the selected folder have been duplicated in JPEG format."
end tell

【问题讨论】:

    标签: image macos applescript jpeg converter


    【解决方案1】:

    从文件名的角度来看,听起来您只需要从文件名中去掉 .NEF 扩展名。您可以通过使用“.”将文件名字符串转换为列表来完成此操作。作为分隔符,从列表中删除最后一项,然后将列表重新组合为文件名字符串。我认为应该这样做(插入“重复”块):

        set theImage to file ((item a of theImages) as string)
        tell application "Finder" to set fileTimestamp to creation date of theImage
        set theImageReference to open theImage
        tell theImageReference
            set theImageName to name
            set savedDelimiters to AppleScript's text item delimiters
    -- Split filename string into list, using "." as a delimiter
            set AppleScript's text item delimiters to {"."}
            set delimitedList to every text item of theImageName
    
    -- Remove the .NEF extension from the list, if it was there
            ignoring case
                if last item of delimitedList is "NEF" then
                    set filenameList to items 1 thru -2 of delimitedList
                    set theImageName to filenameList as string
                end if
            end ignoring
    
    -- Restore delimiters to default in case of other users
            set AppleScript's text item delimiters to savedDelimiters
    
    -- Construct full path of file to save
            set saveImageName to ((theOutputFolder as string) & theImageName & ".JPG")
    
    -- Check for file existence
            tell application "Finder"
                if exists file saveImageName then
    -- Check with user - skip to the next file if user doesn't want to overwrite
                    if button returned of (display dialog saveImageName & " already exists.  Overwrite?" buttons {"Yes", "No"}) is "No" then exit repeat
                end if
            end tell
    
    -- Save the file
            set saveImageName to save in saveImageName as JPEG
    
    -- Fiddle the timestamp of the saved file
            tell application "Finder" to set modification date of saveImageName to fileTimestamp
        end tell
    

    注意,我认为您不能轻易更改 .JPG 文件的创建日期(它是 finder 字典中的 ar/o 属性。我能做的最好的事情就是设置 .JPG 文件的修改日期到 .NEF 文件的创建日期。

    【讨论】:

      【解决方案2】:

      非常感谢您非常,原子牙刷!

      如果不保存评论,我似乎无法在评论中插入空白行或在此处标记为代码,所以这里有一个后续作为答案。真的,它更像是一个修订后的问题。 :}

      在我看来,它非常接近于希望的工作。我用你建议的迷人的 sn-p 替换了重复部分中的代码,尽管我还没有完全理解它在做什么。在目标文件夹中有一个文件时,脚本会中止突出显示“别名”一词,并显示以下消息:

      error "File Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG wasn’t found." number -43 from "Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG"
      

      在目标文件夹中有两个文件并删除“别名”后,它创建 DSC_2070.JPG 就好了,但不会更改模组日期并中止此消息:

      error "Can’t set modification date of \"Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG\" to date \"Wednesday, August 28, 2013 1:03:29 PM\"." number -10006 from modification date of "Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG"
      

      如果我像上面那样运行一次以创建 JPG 文件,然后重新添加“作为别名”并再次运行它会更改日期(用于创建和修改!)以匹配源文件但随后中止使用此消息突出显示 Repeat 中的最后一个 Tell:

      error "File Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG wasn’t found." number -43 from "Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG"
      

      看起来它正在记住最后处理的文件,因为如果我重命名文件,删除“作为别名”并再次运行它,它会中止突出显示重复中相同的最后一个 Tell 行,此消息引用不再存在的文件名文件夹:

      error "Can’t set modification date of \"Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG\" to date \"Wednesday, August 28, 2013 1:14:19 PM\"." number -10006 from modification date of "Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG"
      

      插入重复字符串的完整脚本,如上测试:

      set theImageFolder to choose folder with prompt "Select a folder with NEF images to convert into JPEG images:"
      set theOutputFolder to theImageFolder
      
      tell application "Finder"
          set theImages to every file of theImageFolder whose name extension is "NEF"
      end tell
      
      tell application "Image Events"
          launch
          repeat with a from 1 to length of theImages
              set theImage to file ((item a of theImages) as string)
              tell application "Finder" to set fileTimestamp to creation date of theImage
              set theImageReference to open theImage
              tell theImageReference
                  set theImageName to name
                  set savedDelimiters to AppleScript's text item delimiters
                  set AppleScript's text item delimiters to {"."}
                  set delimitedList to every text item of theImageName
                  ignoring case
                      if last item of delimitedList is "NEF" then
                          set filenameList to items 1 thru -2 of delimitedList
                          set theImageName to filenameList as string
                      end if
                  end ignoring
                  set AppleScript's text item delimiters to savedDelimiters
                  set saveImageName to ((theOutputFolder as string) & theImageName & ".JPG") as alias
                  save in saveImageName as JPEG
                  tell application "Finder" to set modification date of saveImageName to fileTimestamp
              end tell
          end repeat
      end tell
      tell application "Finder"
          display alert "Done.  All NEF files in the selected folder have been duplicated in JPEG format with modification date and time changed to match the NEF source file."
      end tell
      

      【讨论】:

      • 你是对的 - 我没有像我应该做的那样彻底地测试这个。我已经编辑了我的原始答案 - 我认为它现在应该可以按您的预期工作。顺便说一句,您不了解脚本的哪一部分?我可以帮你解释一下你有兴趣。
      • 酷!我会检查一下并回复你。至于我的理解不够,也许我会尝试在代码中添加一些注释并重新发布整个脚本供您检查。我知道注释的脚本和代码对我作为一个临时用户非常有帮助,所以也许它会帮助任何其他搜索此问题的解决方案并找到此线程的人。
      • 好的,所以看起来您只更改了这两行:1.将 saveImageName 设置为 ((theOutputFolder as string) & theImageName & ".JPG") as alias ["as alias" dropped] 2.在 saveImageName 中另存为 JPEG [“将 saveImageName 设置为”前置]。现在来测试...
      • 源/输出文件的所有日期/时间信息都匹配。正确处理包含空格或以“.NEF.JPG”结尾的文件。如果再次运行,它会再次处理 NEF 文件并替换现有的 JPG。这意味着它会覆盖任何现有的同名 JPG,所以我会尝试添加一些东西来防止这种情况发生。我还将尝试将文件名输出添加到重复,以便用户在处理名称时看到名称。如果用户想要文件大小权衡(非常好),还将考虑将 JPG 质量变量添加到图像事件调用中。仍在测试,并开始评论...
      • 在你的问题中,我知道你建议我现在停止,因为它工作得很好?真的不需要为自己检测/避免重新处理 JPG,因为我只会在不包含 JPG 的文件夹上使用它,并且可以在初始对话框中警告用户。我想象添加某种进度指示器会很容易,但是自从在循环中添加简单 ECHO 的过去以来,事情已经“进步”了。 :) 我在 mactech.com/articles/mactech/Vol.22/22.01/ProgressFeedback 找到了一些东西,但可能会放手。我仍然会添加 cmets 并为后代发布决赛。
      【解决方案3】:

      您也可以使用sips 转换图像,使用touch -r 更改修改(和创建)时间:

      for f in *.nef; do jpg="${f%nef}jpg"; sips -s format jpeg -s formatOptions 90 "$f" -o "$jpg"; touch -r "$f" "$jpg"; done

      touch -r通常只改变修改和访问时间,但如果目标时间早于原始创建时间,它也会改变创建时间。

      如果文件的创建和修改时间不同,可以使用SetFileGetFileInfo

      SetFile -m "$(GetFileInfo -m "$f")" "$jpg"; SetFile -d "$(GetFileInfo -d "$f")" "$jpg"

      -m 更改修改时间,-d 更改创建时间。 SetFileGetFileInfo 是命令行工具包的一部分,可以从 developer.apple.com/downloads 或 Xcode 的首选项中下载。

      【讨论】:

      • 这让我想知道 shell 脚本是否可以复制每个 NEF 文件,将扩展名更改为 JPG,然后强制将其作为 NEF 打开并另存为 JPG,以便它可能具有原始文件的创建日期和修改转换为 JPG 的日期。但正如我在最初的帖子中所说,我更喜欢使用 AppleScript,因为大部分代码已经可以工作了。 AppleScript 偏好中一个更大的考虑是发现我最初的手动预览转换产生了如此出色的结果,我想使用相同的底层 Apple 应用程序,而 Image Events 似乎可以做到这一点。
      • Image Events 和 sips 都使用 Core Image,man sips 表示 sips 的功能“也可以通过“Image Events”AppleScript 套件使用”。
      • 很高兴知道。如果有人想用 shell 脚本来做,我们现在拥有的出色的 AppleScript 可能会更快并启用更多功能。我更愿意使用 shell 脚本来完成它,以了解更多关于在功能和可移植性方面远远超出 AppleScript 的环境。
      猜你喜欢
      • 1970-01-01
      • 2017-09-10
      • 2014-07-01
      • 1970-01-01
      • 2021-08-22
      • 2021-10-31
      • 2013-09-20
      相关资源
      最近更新 更多