0

I'm trying to use the tkinter solution for obtaining clipboard image data copied from GIMP, but cannot make it work, saving the data to file:

from tkinter import Tk
r = Tk()
r.withdraw()
clip = r.clipboard_get(type="image/png")
r.update()
r.destroy()
with open("testbytes.png", mode="bw+") as f:
    f.write(clip.encode())

When I try to open the testbytes.png file, the Image Viewer reports a fatal error, not a PNG file. I obtained the type parameter for the clipboard_get() call with r.selection_get(selection='CLIPBOARD', type='TARGETS'), which returned:

'TIMESTAMP TARGETS MULTIPLE SAVE_TARGETS image/png image/bmp image/x-bmp image/x-MS-bmp image/x-icon image/x-ico image/x-win-bitmap image/vnd.microsoft.icon application/ico image/ico image/icon text/ico image/tiff image/jpeg '

I think the format of the data on the clipboard is PNG. I've also tried JPEG, BMP and TIFF, but they result in similar errors.

What am I doing wrong?

Theo d'Or
  • 783
  • 1
  • 4
  • 17
  • Have you looked in the file to see what it looks like, or used some other tool that can attempt to detect the file type? Also, why are you calling `encode` on the data? – Bryan Oakley Jan 24 '19 at 16:19
  • @BryanOakley During the various tests that I was doing, Python reported the type of data on the clipboard being `str`. I use `encode` to get `bytes`. The data looks like this - `b'0x89 0x50 0x4e 0x47 0xd 0xa 0x1a 0xa 0x0 0x0 0x0 0xd 0x49...`. I don't know what other tool to use to get file type. – Theo d'Or Jan 24 '19 at 16:40
  • I have now run the `file testbytes.png` command in Terminal and get this response: `testbytes.png: ASCII text, with very long lines, with no line terminators`. Not what it should be, is it? – Theo d'Or Jan 24 '19 at 16:55
  • `b'0x89 0x50 0x4e ...` isn't PNG data, it's a hex dump of PNG data. – jasonharper Jan 24 '19 at 17:37
  • @jasonharper Thanks for that! Running `xxd -r -p testbytes.hex > testbytes.png` to convert the hex dump to binary, produces a file that in Image Viewer results in the "PNG file corrupted by ASCII conversion" error. This error results both when I save the original string read from the clipboard, as well as when encoding to bytes. Doing some searches on the topic of hexdump-to-binary conversion, it appears such conversions are not always straightforward. I need to find out what's wrong with the hexdump and a method of converting correctly. – Theo d'Or Jan 24 '19 at 19:07

2 Answers2

0

Using a conversion method, obtained in a separate SO question, for the hexdump of PNG data that tkinter provides from the clipboard, the correct code is:

from tkinter import Tk
r = Tk()
r.withdraw()
clip = r.clipboard_get(type="image/png")
r.update()
r.destroy()
# Convert hexdump to bytes
clip = bytes([eval(h) for h in clip.strip().split(' ')])
with open("testbytes.png", mode="bw+") as f:
    f.write(clip)

Apart from writing out a PNG file, the data may also be loaded with the pillow module (formerly known as PIL):

import io
from PIL import Image
cf = io.BytesIO(clip)
cim = Image.open(cf)
cim.show()

As far as I've been able to determine, this is the best method of reading a PNG file from the clipboard into Python 3 on Linux (Debian).

Theo d'Or
  • 783
  • 1
  • 4
  • 17
0

I have created a tool for this intended for windows. The code could be used for debian as well. This script monitors for change in your clipboard and pops up a tkinter window asking you the filename to be used for saving the image, if it is not present in the folder. The image is then saved into the folder as a PNG file. It is particularly helpful with the windows shortcut Windows + Shift + S used to snip the screen.

Please find it here: https://github.com/Mitzzzzz/Clipboard-Image-Saver

Mithil Mohan
  • 223
  • 2
  • 11