我们的论坛(Discourse)、GitHub、Pages.app 和一些 Markdown 编辑器都有这个功能。
所幸 Emacs Mac Port 支持剪切板中图片格式(不清楚其它的 Emacs),下面利用它实现同样的功能,因为图片数据常常是 TIFF 格式的,所以我用 ImageMagick 转换成 PNG。
(defun insert-image-from-clipboard ()
"保存剪切板图片为 clipboard.png,插入 Markdown 图片链接."
(interactive)
(if-let* ((s
;; `gui-selection-value' is not reliable
(gui--selection-value-internal 'CLIPBOARD))
(prop (get-text-property 0 'display s))
(data (pcase prop (`(image . ,plist) (plist-get plist :data))))
(file "clipboard.png"))
(progn
(let ((coding-system-for-write 'binary))
(write-region data nil file))
;; Convert TIFF into PNG
(shell-command (format "convert %s %s" file file))
(cond ((derived-mode-p 'markdown-mode)
(insert (format "![](%s)" file)))
((derived-mode-p 'org-mode)
(insert (format "file:%s" file)))
(t (insert file))))
(user-error "No image in clipboard")))
2 个赞
Windows上利用imagemagick也可以完美支持剪贴板图片。
2 个赞
不知道 ImageMagick 能读取剪切板,貌似只支持 Windows,在 macOS 用以下命令试了下:
~ $ magick clipboard: test.png
magick: unable to open image 'clipboard:': No such file or directory @ error/blob.c/OpenBlob/3485.
magick: no decode delegate for this image format `' @ error/constitute.c/ReadImage/556.
~ $
用命令行工具读取剪切板应该是最 Portable 的方案了,我怀疑除了 Emacs Mac Port,其它 Emacs 都不支持读取剪切板中的图片,Eli Zaretskii 说过:
Emacs doesn’t yet support non-text content of the clipboard, certainly not on MS-Windows. Volunteers are very welcome to work on that.
https://www.reddit.com/r/emacs/comments/8wikaj/paste_image_from_clipboard_on_both_mac_pc/e1w23rc/
分享一下我在windows下的的粘贴函数,需要安装imagemagick。
- 使用任何应用软件截屏或者复制图片到剪贴板,在org-mode里粘贴即可。图片会自动保存到当前文件目录下的images文件夹里。
- 该函数支持粘贴剪贴板的文字和图片,所以你可以将
Ctrl-y
绑定到该函数上,然后如粘贴文字一样粘贴图片,当然文字也OK。
-
Ctrl-u Ctrl-y
会提示为图片命名,并在文档中引用该图片,同时会提示为图片插入caption。
- 在org capture buffer中粘贴时,该函数会找到目标文件的目录,并将图片保存到该目录中。
(defun org-insert-clipboard (&optional captionp)
(interactive "P")
(let* ((image-dir
(if (not (buffer-file-name))
(cond ((string-prefix-p "CAPTURE-[0-9]" (buffer-name))
(let ((buffer-name (replace-regexp-in-string "CAPTURE-[0-9-]*" "" (buffer-name))))
(concat (file-name-directory (buffer-file-name (get-file-buffer buffer-name))) "images")))
(t (yank) (error "")))
"images"))
(fname (concat (make-temp-name "image-") (format-time-string "%Y%m%d-%H%M%S")))
(image-file (concat image-dir "/" fname ".png"))
(exit-status
(call-process "convert" nil nil nil
"clipboard:" image-file)))
(if (zerop exit-status)
(progn
(unless (file-exists-p image-dir) (make-directory image-dir))
(if captionp
(let ((rename (read-string "Filename to rename the temp images: ")))
(rename-file image-file (concat image-dir "/" rename ".png") t)
(insert (format "#+CAPTION: %s label:fig:%s\n" (read-string "Caption: ") rename))
(kill-new (format "Fig. ref:fig:%s " rename)))
(insert (format "[[file:%s]]" image-file))
(org-display-inline-images)))
(when captionp (user-error "No images in clipboard."))
(yank))))
7 个赞
mac 可以这样实现, 需要借助外部命令行工具 pngpaste
(defun insert-image-from-clipboard ()
"保存剪切板图片为 Y-m-d-H-M-S.png,插入 Markdown/Org 图片链接."
(interactive)
(progn
(setq file (format-time-string"%Y-%m-%d-%H-%M-%S.jpg"))
(cond ((derived-mode-p 'markdown-mode)
(unless (file-exists-p (file-name-directory "imgs/"))
(make-directory (file-name-directory "imgs/")))
(call-process-shell-command (format "pngpaste imgs/%s" file))
(insert (format "![](%s)" file)))
((derived-mode-p 'org-mode)
(unless (file-exists-p (file-name-directory "imgs/"))
(make-directory (file-name-directory "imgs/")))
(call-process-shell-command (format "pngpaste imgs/%s" file))
(insert (format "[[./imgs/%s]]" file))))
))
大概是这样,会在 org/md 的同级目录下新建一个 imgs 目录,剪切板中的图片会保存在这个目录中,如果不想用这个形式或者不想用这个路径保存,可以自己调整。
1 个赞