I want to copy images from Emacs to macOS clipboard. I have tried selecting them and yanking, which hasn't worked. Google also didn't have a solution.
-
Not exactly a duplicate, but a similar question: emacs.stackexchange.com/questions/26418/…– aplaiceCommented Apr 14, 2018 at 16:32
-
@Dan I want to copy the image files to macOS clipboard. I have tried selecting the image and pressing 'y'.– HappyFaceCommented Apr 15, 2018 at 15:24
2 Answers
A very rudimentary function that will yank the displayed image at point to the X11 clipboard:
(defun x11-yank-image-at-point-as-image ()
"Yank the image at point to the X11 clipboard as image/png."
(interactive)
(let ((image (get-text-property (point) 'display)))
(if (eq (car image) 'image)
(let ((data (plist-get (cdr image) ':data))
(file (plist-get (cdr image) ':file)))
(cond (data
(with-temp-buffer
(insert data)
(call-shell-region
(point-min) (point-max)
"xclip -i -selection clipboard -t image/png")))
(file
(if (file-exists-p file)
(start-process
"xclip-proc" nil "xclip"
"-i" "-selection" "clipboard" "-t" "image/png"
"-quiet" (file-truename file))))
(t
(message "The image seems to be malformed."))))
(message "Point is not at an image."))))
Requirements
You need to have xclip
installed.
Limitations
Only works on a system with X11 (i.e. won't easily work on MacOS, Windows etc.). Unfortunately, it seems that
pbpaste
, which is usually a drop-in replacement forxclip
cannot copy an image to the clipboard. For possible workarounds, see here. I don't have access to a MacOS system, so I can't apply these myself.xclip
cannot currently copy to multiple targets/atoms (github issue), so programs that can't deal with theimage/png
target atom, will either ignore the paste from the clipboard or insert the image as binary "text".(Relatively easily circumventable.) Currently, the atom used is
image/png
irrespective of whether the image is actually apng
or not. However, it seems that the programs that can deal with an "image" target atom (such asgimp
orinkscape
) seem to (somehow) correctly deal with the paste, even if the image was not apng
. If needed, this could be circumvented by first inspecting the image type and selecting the target atom based on that.
Miscellaneous
Region
For a region, (get-text-property (text-property-not-all (point-min) (point-max) 'display nil) 'display)
would get you the first image (or other "special" display
property) in the region. The other property search functions might also be helpful.
Debugging :data
Try:
(let ((data (plist-get
(cdr (get-text-property (point) 'display))
':data))
(coding-system-for-write 'no-conversion))
(with-temp-buffer
(insert data)
(save-buffer)))
(you will be prompted about the location where to save).
-
1Thanks! I made it work in macOS. I will post it as another answer. Commented Apr 15, 2018 at 16:02
-
This only works when the point is exactly before the image. How can I make it work for regions? Or when the point is after the image? Commented Apr 15, 2018 at 16:06
-
-
I have done some testing for the data case, using pbcopy instead of impbcopy. Running 'pbpaste > t.jpg' results in a corrupt file. Here is the data variable: gist.github.com/NightMachinary/2c67957b1aa8261679d9d973a5f6366a Commented Apr 15, 2018 at 16:48
-
I've edited the answer with some suggestions. I've also made it into a "community wiki" so you can change it, if you want. Looking at the data in the gist, it does indeed seem to be corrupt, but I'm not sure why.– aplaiceCommented Apr 15, 2018 at 18:28
From @aplaice's answer, adapted to macOS:
(defun ns-yank-image-at-point-as-image ()
"Yank the image at point to the X11 clipboard as image/png."
(interactive)
(let ((image (get-text-property (point) 'display)))
(if (eq (car image) 'image)
(let ((data (plist-get (cdr image) ':data))
(file (plist-get (cdr image) ':file)))
(cond (data
(with-temp-buffer
(insert data)
(call-shell-region
(point-min) (point-max)
"impbcopy"))) ;; http://www.alecjacobson.com/weblog/?p=3816 Linux x11: https://emacs.stackexchange.com/questions/41016/how-can-i-yank-images-from-emacs?noredirect=1#comment64407_41016
(file
(if (file-exists-p file)
(start-process
"_" nil "impbcopy" (file-truename file))))
(t
(message "The image seems to be malformed."))))
(message "Point is not at an image."))))