一小段在windows下适用的粘贴图片的代码

org-download 目前在windows下已经失效了,我看修复的pr也没有合并(新的pr看起来引入了额外的依赖),然后就查了查网上其他的资料,最后结合 ai 搞出来了这段代码

将会尝试读取剪切板的图片,然后把它保存到当前buffer对应文件同路径下的image文件夹中,命名格式是用的时间戳,保存时会要求用户选择png格式还是jpg格式

本质上就是调用的pwsh,来对图片格式进行转换,和保存,整体选择是同步方式执行命令,这样方便获取结果,并且效果理论是最好的

(if (eq system-type 'windows-nt)
    (defun paste-img ()
      (interactive)
      (let* ((file-path (buffer-file-name))
             (directory (if file-path
                            (file-name-directory file-path)
                          (error "No associated file for the current buffer")))
             (image-directory (expand-file-name "image" directory))
             (timestamp (format-time-string "%Y%m%d_%H%M%S"))
             (format (completing-read "Select image form:" '("png" "jpg")))
             (image-name (format "image_%s.%s" timestamp format))
             (image-path (expand-file-name image-name image-directory))
             (image-format (if (string= format "jpg") "Jpeg" "Png"))
             (script (format "Add-Type -AssemblyName System.Windows.Forms; $clipboardImage = [System.Windows.Forms.Clipboard]::GetImage(); if ($clipboardImage -ne $null) { $clipboardImage.Save('%s', [System.Drawing.Imaging.ImageFormat]::%s); Write-Host 'Image saved'; } else { Write-Host 'No image in clipboard'; }" image-path image-format)))

        (unless (file-exists-p image-directory)
          (make-directory image-directory t))

        (call-process "pwsh" nil nil nil "-Command" script)

        (if (file-exists-p image-path)
            (progn
              (insert (format "[[file:%s]]" (concat "image/" image-name))) ;          
              (message "Image successfully saved to: %s" image-path))
          (message "No image in clipboard or image not saved")))))

1 个赞

然后就是额外提问了,linux下保存图片还有其他的方案吗

除了org-download,这个插件看起来作者已经弃坑了

我只需要粘贴图片就行,我看xclip没法直接将图片保存为png或者jpg格式?

如果用的是 最新的 emacs org-9.7 ,可以用自带的 yank-media ,能粘贴网络图片并且选择不同的格式。它理论上能处理其他情况,但我在粘贴系统截屏的遇到 bug ,从没有成功过。(我的系统是 gnome, 相关的 bug 是 bug#72254: 29.4; Cannot yank media when image come from Gnome-shell scre

最新是指 master分支? 还是stable版本 29

刚刚查了一下,这是 org 9.7 引入的功能:Release notes | Org mode


New features Images and files in clipboard can be pasted

Org asks the user what must be done when pasting images and files copied to the clipboard from a file manager using the yank-media command. The default action can be set by customizing org-yank-dnd-method. The yank-media command was added in Emacs 29.

嗯,我尝试了一下,然后提示我没有对应org mode的handle 关于注册handle,有啥示例吗

你的 org 版本是 9.7 吗,目前 release 的 emacs-29.4 内置 org 版本还是旧的。

如果正常的话,在粘贴网络图片时不需要任何配置就可以成功运行。另外要注意目前也不支持 windows :


Note that yank-media, as of Emacs 30, does not yet support Windows (Emacs bug#71909) and may not be always reliable on Mac (Emacs bug#71731).

看了一下,用的还是内置的org,我更新试试

org用的9.8,然后拖动文件进去会变成奇怪的乱码

这里是拖动一个网页上的图片进去, 如果我复制再yank-media就正常

我自己试的时候也只有复制然后 M-x yank-media 能用。拖拽功能根据更新文档上说的也实现了,但就是不能用,问题估计还是在 emacs 本体这边,只能等以后修复了。

这个函数支持从 Windows 剪贴板复制图片, 理论它适用所有 mode…
要想改变要保存的路径, 可以理解:
(attach-dir (concat current-dir “attach/” file-name-base “/”))

代码实现如下:

  ;; 支持 Windows 从剪贴板复制图片
  (defun freedom/insert-image-from-clipboard ()
    "Insert an image from the clipboard into the current org buffer."
    (interactive)
    (let* ((current-dir (file-name-directory buffer-file-name))
           (file-name-base (file-name-base buffer-file-name))
           (attach-dir (concat current-dir "attach/" file-name-base "/"))
           ;; (attach-dir (concat current-dir "attach/"  (file-name-nondirectory buffer-file-name) "/"))
           (image-file (concat attach-dir (format-time-string "%Y%m%d_%H%M%S") ".png")))
      ;; Ensure attach directory exists
      (unless (file-exists-p attach-dir)
        (make-directory attach-dir t))
      ;; Save the clipboard image to the attach directory
      (if (eq system-type 'windows-nt)
          (progn 
            (shell-command (concat "powershell -command \"Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.Clipboard]::GetImage().Save('" image-file "', [System.Drawing.Imaging.ImageFormat]::Png)\""))
            ;; 转换格式, 从 c:/Users/Jack/Desktop/attact/test/clipboard.png 之类
            ;; 转换成 ./attach/test/clipboard.png
            (setq image-file (replace-regexp-in-string
                              "^[^:]+:/.*\\(/attach/.*\\)" ".\\1" image-file))
            (when (eq major-mode 'org-mode)
              ;; 输入文件所在位置文本
              (insert (concat "[[file:" image-file "]]"))
              ;; 显示图片
              (org-display-inline-images))
            (when (eq major-mode 'markdown-mode)
              (insert (concat "![]" "(" image-file ")"))
              (markdown-display-inline-images))
            )
        (error "Unsupported OS"))
      ))
2 个赞