我正在使用Tkinter中的画布,并尝试将该画布的内容复制到剪贴板。
我可以通过创建文件并将该文件的内容复制到剪贴板来解决此问题,例如用xclip -selection clipboard -t image/png -i temp_file.png
,但我想使用缓冲区,使用户能够直接将其复制到剪贴板而不触及用户的文件系统。
要使用xclip
的输入功能,我需要提供一个文件名,而不是一个字符串。我可以通过在Bash命令行中使用echo/cat作为cat temp_file.png < echo | xclip -selection clipboard -t image/png -i
或cat file_name.png | xclip -selection clipboard -t image/png -i
来规避这个问题。
我已经成功地使用缓冲区存储画布,如下所示:
memory = io.BytesIO()
img.save(memory, format="png")
return memory
并且可以将图片保存到文件中,方法如下:
img = pil.Image.open(memory)
img.save("file_name.png", format="png")
据我所了解,根据PIL的文档,
pil.Image.open
与内置函数open()
是相同的。然而,当尝试使用open()
来读取文件时,它声称BytesIO不是有效的文件。不过,我想这不是什么大问题。我可以使用
memory.getvalue()
读取缓冲区的内容,然后用[2:-1]去掉周围的b'...'
。我再用\'
替换字符串中所有的'
,这样就可以用单引号将其括起来,并最终通过之前对某个文件使用的命令来输出该字符串。img_data = str(img_memory.getvalue())[2:-1]
img_data = img_data.replace("'", "\'")#.replace("`", "\`")
img_data = "'" + img_data + "'"
< p > cat file_name.png
的输出与我在子进程中给出的字符串的echo
命令的输出几乎相同,但是以下操作对我似乎没有用,因为我的剪贴板保持不变:
bash_cmd = f"echo -n {img_data} | xclip -selection clipboard -t image/png -i"
p = sp.Popen(bash_cmd, shell=True, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE)
但是
bash_cmd = f"xclip -selection clipboard -t image/png -i file_name.png"
p = sp.Popen(bash_cmd, shell=True, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE)
有用。
简而言之
我做错了什么?我是否修改了文件内容,从而创建了一个损坏的图像,然后进行复制?
我应该如何正确地将io.BufferIO
的内容输出到剪贴板中(主要是在Unix/Linux上,但也适用于MacOS/Windows)?