Created
January 3, 2026 22:26
-
-
Save vherrmann/1b836fb4b3094777d29b06ca60b554cf to your computer and use it in GitHub Desktop.
Attaching images from the phone in org mode
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (cl-defun iko/run-process-async (name program &key stdin args on-exit) | |
| "Run PROGRAM asynchronously with ARGS, outputting to BUFFER-NAME." | |
| (with-current-buffer (get-buffer-create (concat "*" name "*")) | |
| (let ((b (current-buffer)) | |
| (p (apply #'start-process name (current-buffer) program args))) | |
| (set-process-sentinel | |
| p | |
| (lambda (proc event) | |
| (when (eq (process-status proc) 'exit) | |
| (when on-exit | |
| (funcall on-exit | |
| (process-exit-status proc) | |
| (with-current-buffer b (buffer-string)) | |
| proc | |
| event)) | |
| (kill-buffer b)))) | |
| (when stdin | |
| (process-send-string p (if (string-suffix-p "\n" stdin) | |
| stdin | |
| (concat stdin "\n"))) | |
| (process-send-eof p)) | |
| p))) | |
| (defun iko/scale-image-to-max-size (input-file output-file &optional max-width max-height) | |
| "Downscale INPUT-FILE to fit within MAX-WIDTH x MAX-HEIGHT (default 1280x720) and save as OUTPUT-FILE." | |
| (let ((max-width (or max-width 1280)) | |
| (max-height (or max-height 720))) | |
| ;; Call ImageMagick 'convert' to resize while keeping aspect ratio | |
| (call-process | |
| "convert" nil nil nil | |
| input-file | |
| "-resize" (format "%dx%d>" max-width max-height) | |
| output-file) | |
| (message "Saved scaled image to %s" output-file))) | |
| (defun iko/yad-select-img-from-dir (dir) | |
| "Use yad to select a file from DIR. Returns the selected file path." | |
| (let* ((command (s-join " " | |
| `("yad" | |
| "--file" | |
| "--filter=\"Images | *.png *.jpg *.jpeg *.gif *.webp *.bmp\"" | |
| "--title=\"Select Image\"" | |
| "--add-preview" | |
| "--large-preview" | |
| ,(format "--workdir=%s" dir)))) | |
| (output (string-trim (shell-command-to-string command)))) | |
| (if (and (not (string-empty-p output)) | |
| (file-exists-p output)) | |
| output | |
| (user-error "No file selected or yad failed")))) | |
| (defun iko/org-attach-image-from-phone () | |
| (interactive) | |
| (let* ((attachDir ATTACHMENTS_CACHE_DIR) | |
| (user YOUR_USERNAME) | |
| (password YOUR_PASSWORD) | |
| (server YOUR_SERVER) | |
| (args | |
| `("-u" ,user | |
| "--path" ,NEXTCLOUD_FOLDER | |
| ,attachDir | |
| ,server))) | |
| (f-mkdir-full-path attachDir) | |
| (iko/run-process-async | |
| "nextcloudcmd-download" | |
| "nextcloudcmd" | |
| :args args | |
| :stdin password | |
| :on-exit | |
| (lambda (status-code _output _proc _event) | |
| (when (/= status-code 0) | |
| (user-error "nextcloudcmd failed with code %s" status-code)) | |
| (let ((img-file (iko/yad-select-img-from-dir attachDir))) | |
| (message "selected %s" img-file) | |
| (when img-file | |
| (let ((tmpfile (make-temp-file "scaled-img-" nil ".png"))) | |
| (message "buffer file: %s" tmpfile) | |
| (iko/scale-image-to-max-size img-file tmpfile) | |
| (org-download-image (concat "file://" tmpfile)) | |
| (message "attached %s" img-file)))))))) |
Author
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I recently developed the following workflow to attach images from my phone in emacs org mode.
First, I created the folder
NEXTCLOUD_FOLDERon my nextcloud instance and used the nextcloud app on my phone to create photos in that folder.Then I execute
iko/org-attach-image-from-phonein an org mode document where I want the image to be attached usingorg-attach/org-download.Emacs then first syncs
NEXTCLOUD_FOLDERwithATTACHMENTS_CACHE_DIR. On success I am prompted withyadto choose the attachment among the files inATTACHMENTS_CACHE_DIR. It is then sized down to 720p withimagemagick; otherwise the preview in emacs is too slow. Finally, the image is attached to the current node and a link to it is written into the file at point.To use it, you need to install
yad,nextcloudcmdandimagemagickon your machine, as well asorg-download,s.elandf.elin your emacs. Finally, you need to configureATTACHMENTS_CACHE_DIR,YOUR_USERNAME,YOUR_PASSWORD,YOUR_SERVERandNEXTCLOUD_FOLDER.