├── .gitignore ├── Change DPI to 72.applescript ├── Change DPI to 90.applescript ├── Change DPI to XY.applescript ├── Generate image set (HTML).applescript ├── Generate image set (Markdown).applescript ├── Image auto-rename and annotate.applescript ├── JPG compress 100%.applescript ├── JPG compress 70%.applescript ├── JPG compress 80%.applescript ├── JPG compress XY%.applescript ├── LICENSE ├── README.md └── Screenshots ├── Change DPI 1.png ├── Change DPI 2.png ├── DT_Image Toolbox logo.png ├── Generate image set.png ├── Image auto-rename and annotate menu.png ├── Image set example (edit view).jpg ├── Image set example (preview).jpg ├── JPG compression 1.png ├── JPG compression 2.png ├── img058627.png ├── img058628.png └── img058629.png /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ -------------------------------------------------------------------------------- /Change DPI to 72.applescript: -------------------------------------------------------------------------------- 1 | -- Change the DPI of an image 2 | -- 3 | -- author: Fabrizio Musacchio (https://www.fabriziomusacchio.com) 4 | -- date: Feb 3, 2022 5 | 6 | tell application id "DNtp" 7 | try 8 | set this_selection to the selection 9 | if this_selection is {} then error "Please select some images." 10 | repeat with this_item in this_selection 11 | if the type of this_item is equal to picture then 12 | try 13 | set this_image to the image of this_item 14 | with timeout of 30 seconds 15 | tell application "Image Events" 16 | launch 17 | set this_file to open file this_image 18 | set the scalefactor to 72 19 | set thePathShell to quoted form of this_image 20 | do shell script "sips -s format jp2 -s formatOptions normal -s dpiHeight " & scalefactor & " -s dpiWidth " & scalefactor & " " & thePathShell 21 | do shell script "sips -s format jpeg -s formatOptions normal -s dpiHeight " & scalefactor & " -s dpiWidth " & scalefactor & " " & thePathShell 22 | close this_file 23 | end tell 24 | end timeout 25 | synchronize record this_item 26 | end try 27 | end if 28 | 29 | --set current_name to the name of this_item 30 | --set new_item_name to current_name -- & "_fullWidth_" & W & "_" & scalefactor & "_" & R 31 | --set the name of this_item to new_item_name 32 | 33 | end repeat 34 | on error error_message number error_number 35 | if the error_number is not -128 then display alert "DEVONthink" message error_message as warning 36 | end try 37 | end tell -------------------------------------------------------------------------------- /Change DPI to 90.applescript: -------------------------------------------------------------------------------- 1 | -- Change the DPI of an image 2 | -- 3 | -- author: Fabrizio Musacchio (https://www.fabriziomusacchio.com) 4 | -- date: Feb 3, 2022 5 | 6 | tell application id "DNtp" 7 | try 8 | set this_selection to the selection 9 | if this_selection is {} then error "Please select some images." 10 | repeat with this_item in this_selection 11 | if the type of this_item is equal to picture then 12 | try 13 | set this_image to the image of this_item 14 | with timeout of 30 seconds 15 | tell application "Image Events" 16 | launch 17 | set this_file to open file this_image 18 | set the scalefactor to 90 19 | set thePathShell to quoted form of this_image 20 | do shell script "sips -s format jp2 -s formatOptions normal -s dpiHeight " & scalefactor & " -s dpiWidth " & scalefactor & " " & thePathShell 21 | do shell script "sips -s format jpeg -s formatOptions normal -s dpiHeight " & scalefactor & " -s dpiWidth " & scalefactor & " " & thePathShell 22 | close this_file 23 | end tell 24 | end timeout 25 | synchronize record this_item 26 | end try 27 | end if 28 | 29 | --set current_name to the name of this_item 30 | --set new_item_name to current_name -- & "_fullWidth_" & W & "_" & scalefactor & "_" & R 31 | --set the name of this_item to new_item_name 32 | 33 | end repeat 34 | on error error_message number error_number 35 | if the error_number is not -128 then display alert "DEVONthink" message error_message as warning 36 | end try 37 | end tell -------------------------------------------------------------------------------- /Change DPI to XY.applescript: -------------------------------------------------------------------------------- 1 | -- Change the DPI of an image 2 | -- 3 | -- author: Fabrizio Musacchio (https://www.fabriziomusacchio.com) 4 | -- date: Feb 3, 2022 5 | 6 | tell application id "DNtp" 7 | try 8 | set this_selection to the selection 9 | if this_selection is {} then error "Please select some images." 10 | set dialogResult to display dialog "Please enter a DPI value (e.g., 72, 90, 120, ...)." buttons {"Cancel", "OK"} default button "OK" cancel button "Cancel" default answer ("90") with title "Choose DPI value" 11 | set theDPI to text returned of dialogResult 12 | repeat with this_item in this_selection 13 | if the type of this_item is equal to picture then 14 | try 15 | set this_image to the image of this_item 16 | with timeout of 30 seconds 17 | tell application "Image Events" 18 | launch 19 | set this_file to open file this_image 20 | set the scalefactor to theDPI 21 | set thePathShell to quoted form of this_image 22 | do shell script "sips -s format jp2 -s formatOptions normal -s dpiHeight " & scalefactor & " -s dpiWidth " & scalefactor & " " & thePathShell 23 | do shell script "sips -s format jpeg -s formatOptions normal -s dpiHeight " & scalefactor & " -s dpiWidth " & scalefactor & " " & thePathShell 24 | close this_file 25 | end tell 26 | end timeout 27 | synchronize record this_item 28 | end try 29 | end if 30 | 31 | end repeat 32 | on error error_message number error_number 33 | if the error_number is not -128 then display alert "DEVONthink" message error_message as warning 34 | end try 35 | end tell -------------------------------------------------------------------------------- /Generate image set (HTML).applescript: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FabrizioMusacchio/DEVONthink_Image_Toolbox/50fb2e292b85c6759838d4d72921b42e58589bbe/Generate image set (HTML).applescript -------------------------------------------------------------------------------- /Generate image set (Markdown).applescript: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FabrizioMusacchio/DEVONthink_Image_Toolbox/50fb2e292b85c6759838d4d72921b42e58589bbe/Generate image set (Markdown).applescript -------------------------------------------------------------------------------- /Image auto-rename and annotate.applescript: -------------------------------------------------------------------------------- 1 | -- Auto-rename images and (optionally) annotate them (prior renaming). 2 | -- 3 | -- author: Fabrizio Musacchio (https://www.fabriziomusacchio.com) 4 | -- date: Feb 17, 2022 5 | 6 | 7 | -- Please create an empty DEVONthink document and insert its UUID into the "UUID_of_imager_counter" variable: 8 | property UUID_of_imager_counter : "3E3D7F1F-25A0-4875-B7F1-4D91BE32F24C" 9 | 10 | set leading_zeros to 5 as integer 11 | set CaptionCounter to 0 as integer 12 | set RepeatCounter to 1 as integer 13 | 14 | set MenuChoices to {"Replace with current image name", "Replace with custom text", "Replace with custom text + increasing number", "Don't replace current annotation", "Remove current annotation and leave empty", "Add current image name", "Add custom text", "Add custom text + increasing number"} 15 | set Choice to choose from list MenuChoices with prompt "The selected images will be renamed according the scheme 'img######'. Please select a method to handle the image annotations: 16 | " with title "Auto-rename images and annotate" default items {"Replace with current image name"} 17 | 18 | if Choice is false then 19 | error number -128 20 | else if text of Choice is {"Replace with custom text"} or text of Choice is {"Replace with custom text + increasing number"} or text of Choice is {"Add custom text"} or text of Choice is {"Add custom text + increasing number"} then 21 | set CustomAnnotation to the text returned of (display dialog "Please enter a custom image annotation. Will replace existing annotation." default answer "") 22 | end if 23 | 24 | tell application id "DNtp" 25 | try 26 | set theRecords to every selected record 27 | if theRecords = {} then error "Error: Please select at least one DEVONthink Markdown file." 28 | 29 | 30 | set ImageCounterFile to get record with uuid UUID_of_imager_counter 31 | 32 | activate 33 | show progress indicator "Renaming images" steps (length of theRecords) with cancel button 34 | 35 | repeat with thisRecord in theRecords 36 | -- Update the progress detail 37 | step progress indicator "Step " & (RepeatCounter as string) & "/" & (length of theRecords) as string 38 | if cancelled progress then exit repeat 39 | set RepeatCounter to RepeatCounter + 1 40 | 41 | 42 | set theType to (type of thisRecord) as string 43 | if the type of thisRecord is equal to picture then 44 | --display dialog "Here" buttons {"Okay"} default button "Okay" 45 | set ImageCounter to the plain text of ImageCounterFile 46 | if ImageCounter is "" then 47 | set CounterInit to addLeadingZerosToNumber(1, leading_zeros) of me 48 | set plain text of ImageCounterFile to CounterInit as string 49 | set ImageCounterString to CounterInit as string 50 | else 51 | set ImageCounterString to addLeadingZerosToNumber(((ImageCounter as integer) + 1), leading_zeros) of me as string 52 | set plain text of ImageCounterFile to ImageCounterString 53 | end if 54 | 55 | set TheImageName to thisRecord's name 56 | set ExistingComment to the comment of thisRecord 57 | 58 | 59 | if text of Choice is {"Replace with current image name"} then 60 | set the comment of thisRecord to TheImageName 61 | else if text of Choice is {"Replace with custom text"} then 62 | set the comment of thisRecord to CustomAnnotation 63 | else if text of Choice is {"Replace with custom text + increasing number"} then 64 | set the comment of thisRecord to CustomAnnotation & " " & (CaptionCounter as string) 65 | set CaptionCounter to CaptionCounter + 1 66 | else if text of Choice is {"Don't replace current annotation"} then 67 | --set the comment of thisRecord to ExistingComment 68 | -- do nothing 69 | else if text of Choice is {"Remove current annotation and leave empty"} then 70 | set the comment of thisRecord to "" 71 | else if text of Choice is {"Add current image name"} then 72 | if ExistingComment is not "" then 73 | set the comment of thisRecord to ExistingComment & ". " & TheImageName 74 | else 75 | set the comment of thisRecord to TheImageName 76 | end if 77 | else if text of Choice is {"Add custom text"} then 78 | --set CustomAnnotation to the text returned of (display dialog "Please enter a custom image annotation. Will be appended to existing annotation." default answer "") 79 | if ExistingComment is not "" then 80 | set the comment of thisRecord to ExistingComment & ". " & CustomAnnotation 81 | else 82 | set the comment of thisRecord to TheImageName 83 | end if 84 | else if text of Choice is {"Add custom text + increasing number"} then 85 | --set CustomAnnotation to the text returned of (display dialog "Please enter a custom image annotation. Will be appended to existing annotation." default answer "") 86 | if ExistingComment is not "" then 87 | set the comment of thisRecord to ExistingComment & ". " & CustomAnnotation & " " & (CaptionCounter as string) 88 | set CaptionCounter to CaptionCounter + 1 89 | else 90 | set the comment of thisRecord to TheImageName 91 | end if 92 | end if 93 | 94 | try 95 | set name of thisRecord to "img" & ImageCounterString 96 | end try 97 | 98 | end if 99 | end repeat 100 | hide progress indicator 101 | 102 | on error error_message number error_number 103 | if the error_number is not -128 then display alert "DEVONthink" message error_message as warning 104 | return 105 | end try 106 | end tell 107 | 108 | 109 | 110 | 111 | on addLeadingZerosToNumber(theNumber, theMaxLeadingZeroCount) 112 | -- this function is from https://developer.apple.com/library/archive/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/ManipulateNumbers.html 113 | 114 | -- Determine if the number is negative: 115 | set isNegative to theNumber is less than 0 116 | 117 | -- Determine when the maximum number of digits will be reached: 118 | set theThreshold to (10 ^ theMaxLeadingZeroCount) as integer 119 | 120 | -- If the number is shorter than the maximum number of digits: 121 | if theNumber is less than theThreshold then 122 | -- If the number is negative, convert it to positive: 123 | if isNegative = true then set theNumber to -theNumber 124 | 125 | -- Add the zeros to the number 126 | set theLeadingZeros to "" 127 | set theDigitCount to length of ((theNumber div 1) as string) 128 | set theCharacterCount to (theMaxLeadingZeroCount + 1) - theDigitCount 129 | repeat theCharacterCount times 130 | set theLeadingZeros to (theLeadingZeros & "0") as string 131 | end repeat 132 | 133 | -- Make the number negative, if it was previously negative: 134 | if isNegative = true then set theLeadingZeros to "-" & theLeadingZeros 135 | 136 | -- Return the prefixed number: 137 | return (theLeadingZeros & (theNumber as text)) as string 138 | 139 | -- If the number is greater than or equal to the maximum number of digits 140 | else 141 | -- Return the original number: 142 | return theNumber as text 143 | end if 144 | end addLeadingZerosToNumber 145 | -------------------------------------------------------------------------------- /JPG compress 100%.applescript: -------------------------------------------------------------------------------- 1 | -- Compress a JPEG image to a desired compression level 2 | -- 3 | -- author: Fabrizio Musacchio (https://www.fabriziomusacchio.com) 4 | -- date: Jan 20, 2022 5 | 6 | tell application id "DNtp" 7 | try 8 | set this_selection to the selection 9 | if this_selection is {} then error "Please select some images." 10 | repeat with this_item in this_selection 11 | if the type of this_item is equal to picture then 12 | try 13 | set this_image to the image of this_item 14 | with timeout of 30 seconds 15 | tell application "Image Events" 16 | launch 17 | set this_file to open file this_image 18 | set thePathShell to quoted form of this_image 19 | --do shell script "sips -s format jp2 -s formatOptions normal -s dpiHeight " & scalefactor & " -s dpiWidth " & scalefactor & " " & thePathShell 20 | do shell script "sips -s format jpeg -s formatOptions 100 " & thePathShell 21 | -- formatOptions normal normal means "normal" compression (70%? 80%?). You can also set a number (w/o "%", e.g. 100 (=loss-less)) 22 | close this_file 23 | end tell 24 | end timeout 25 | synchronize record this_item 26 | end try 27 | end if 28 | 29 | --set current_name to the name of this_item 30 | --set new_item_name to current_name -- & "_fullWidth_" & W & "_" & scalefactor & "_" & R 31 | --set the name of this_item to new_item_name 32 | 33 | end repeat 34 | on error error_message number error_number 35 | if the error_number is not -128 then display alert "DEVONthink Pro" message error_message as warning 36 | end try 37 | end tell -------------------------------------------------------------------------------- /JPG compress 70%.applescript: -------------------------------------------------------------------------------- 1 | -- Compress a JPEG image to a desired compression level 2 | -- 3 | -- author: Fabrizio Musacchio (https://www.fabriziomusacchio.com) 4 | -- date: Jan 20, 2022 5 | 6 | tell application id "DNtp" 7 | try 8 | set this_selection to the selection 9 | if this_selection is {} then error "Please select some images." 10 | repeat with this_item in this_selection 11 | if the type of this_item is equal to picture then 12 | try 13 | set this_image to the image of this_item 14 | with timeout of 30 seconds 15 | tell application "Image Events" 16 | launch 17 | set this_file to open file this_image 18 | set thePathShell to quoted form of this_image 19 | --do shell script "sips -s format jp2 -s formatOptions normal -s dpiHeight " & scalefactor & " -s dpiWidth " & scalefactor & " " & thePathShell 20 | do shell script "sips -s format jpeg -s formatOptions 70 " & thePathShell 21 | -- formatOptions normal normal means "normal" compression (70%? 80%?). You can also set a number (w/o "%", e.g. 100 (=loss-less)) 22 | close this_file 23 | end tell 24 | end timeout 25 | synchronize record this_item 26 | end try 27 | end if 28 | 29 | --set current_name to the name of this_item 30 | --set new_item_name to current_name -- & "_fullWidth_" & W & "_" & scalefactor & "_" & R 31 | --set the name of this_item to new_item_name 32 | 33 | end repeat 34 | on error error_message number error_number 35 | if the error_number is not -128 then display alert "DEVONthink Pro" message error_message as warning 36 | end try 37 | end tell -------------------------------------------------------------------------------- /JPG compress 80%.applescript: -------------------------------------------------------------------------------- 1 | -- Compress a JPEG image to a desired compression level 2 | -- 3 | -- author: Fabrizio Musacchio (https://www.fabriziomusacchio.com) 4 | -- date: Jan 20, 2022 5 | 6 | tell application id "DNtp" 7 | try 8 | set this_selection to the selection 9 | if this_selection is {} then error "Please select some images." 10 | repeat with this_item in this_selection 11 | if the type of this_item is equal to picture then 12 | try 13 | set this_image to the image of this_item 14 | with timeout of 30 seconds 15 | tell application "Image Events" 16 | launch 17 | set this_file to open file this_image 18 | set thePathShell to quoted form of this_image 19 | --do shell script "sips -s format jp2 -s formatOptions normal -s dpiHeight " & scalefactor & " -s dpiWidth " & scalefactor & " " & thePathShell 20 | do shell script "sips -s format jpeg -s formatOptions 80 " & thePathShell 21 | -- formatOptions normal normal means "normal" compression (70%? 80%?). You can also set a number (w/o "%", e.g. 100 (=loss-less)) 22 | close this_file 23 | end tell 24 | end timeout 25 | synchronize record this_item 26 | end try 27 | end if 28 | 29 | --set current_name to the name of this_item 30 | --set new_item_name to current_name -- & "_fullWidth_" & W & "_" & scalefactor & "_" & R 31 | --set the name of this_item to new_item_name 32 | 33 | end repeat 34 | on error error_message number error_number 35 | if the error_number is not -128 then display alert "DEVONthink Pro" message error_message as warning 36 | end try 37 | end tell -------------------------------------------------------------------------------- /JPG compress XY%.applescript: -------------------------------------------------------------------------------- 1 | -- Compress a JPEG image to a desired compression level 2 | -- 3 | -- author: Fabrizio Musacchio (https://www.fabriziomusacchio.com) 4 | -- date: Jan 20, 2022 5 | 6 | tell application id "DNtp" 7 | try 8 | set this_selection to the selection 9 | if this_selection is {} then error "Please select some images." 10 | set dialogResult to display dialog "Please enter a JPEG compression level (in %)." buttons {"Cancel", "OK"} default button "OK" cancel button "Cancel" default answer ("70") with title "Choose JPEG compression" 11 | set theCompression to text returned of dialogResult 12 | 13 | 14 | repeat with this_item in this_selection 15 | if the type of this_item is equal to picture then 16 | try 17 | set this_image to the image of this_item 18 | with timeout of 30 seconds 19 | tell application "Image Events" 20 | launch 21 | set this_file to open file this_image 22 | set thePathShell to quoted form of this_image 23 | --do shell script "sips -s format jp2 -s formatOptions normal -s dpiHeight " & scalefactor & " -s dpiWidth " & scalefactor & " " & thePathShell 24 | do shell script "sips -s format jpeg -s formatOptions " & theCompression & " " & thePathShell 25 | -- formatOptions normal normal means "normal" compression (70%? 80%?). You can also set a number (w/o "%", e.g. 100 (=loss-less)) 26 | close this_file 27 | end tell 28 | end timeout 29 | synchronize record this_item 30 | end try 31 | end if 32 | 33 | --set current_name to the name of this_item 34 | --set new_item_name to current_name -- & "_fullWidth_" & W & "_" & scalefactor & "_" & R 35 | --set the name of this_item to new_item_name 36 | 37 | end repeat 38 | on error error_message number error_number 39 | if the error_number is not -128 then display alert "DEVONthink Pro" message error_message as warning 40 | end try 41 | end tell -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Fabrizio Musacchio 2022. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DEVONthink Image Toolbox 2 | 3 | This is a collection of AppleScripts for handling images in DEVONthink. It contains the following script sets: 4 | 5 | * [Image auto-rename and annotate](#image-auto-rename-and-annotate) – renames images according the scheme `img######` and stores the original file name as a comment 6 | * [Generate image set](#generate-image-set) – generates a set of image links, arranged in a desired grid size (1, 2, 3, 4, ... image(s) per row) 7 | * [JPG compression](#jpg-compression) – a JPG compressor and JPG converter 8 | * [Change DPI](#change-dpi) - a DPI changer and JPG converter 9 | 10 |
11 |
12 |
121 |
122 |
123 |
124 |
125 | **Left**: Enso 0 – **Middle**: Enso 1 – **Right**: Enso 2
126 |
151 |
152 |
153 |
154 | Edit view (bottom) and preview (top) of a Markdown file containing an image gallery (some kind of).
155 |
173 |
174 |
175 |
176 | Left: The info pane of a converted TIFF in DEVONthink's inspector, that still shows the file as TIFF. Right: The info pane in macOS' _Preview_ app for the same file, which correctly identifies the file as a JPG.
177 |
189 |
190 |
191 |
192 | Left: The info pane of a JPG file with 72 DPI. Right: The info pane of the same file after a conversion to 90 DPI.
193 |