16

First of all, the question on SO copy image to clipboard in python leads to answer Write image to Windows clipboard in python with PIL and win32clipboard?, which was only good for Python 2.x. -- I tried it and it didn't work. I overcame one problem: StringIO and cStringIO modules are gone in Python 3.0:, but bumped into another one:

TypeError: string argument expected, got 'bytes'

Hence, re-asking the same question again for Python 3 -- How to copy image to clipboard in Python 3? Here is the code I've got so far:

from io import StringIO
import win32clipboard
from PIL import Image

def send_to_clipboard(clip_type, data):
    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardData(clip_type, data)
    win32clipboard.CloseClipboard()

filepath = 'image.jpg'
image = Image.open(filepath)

output = StringIO()
image.convert("RGB").save(output, "BMP")
data = output.getvalue()[14:]
output.close()

send_to_clipboard(win32clipboard.CF_DIB, data)

Thanks

martineau
  • 119,623
  • 25
  • 170
  • 301
xpt
  • 20,363
  • 37
  • 127
  • 216

7 Answers7

12

You don't want StringIO here. Images are raw binary data, and in Py3, str is purely for text; bytes and bytes-like objects (bytearray, contiguous memoryviews, mmaps) are for binary data. To replace Py2's StringIO.StringIO for binary data, you want to use io.BytesIO in Python 3, not io.StringIO.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
11

I did copy the code and replace the StringIO with BytesIO and it worked! (with *.jpg and *.png files) Thank you so much!

from io import BytesIO
import win32clipboard
from PIL import Image

def send_to_clipboard(clip_type, data):
    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardData(clip_type, data)
    win32clipboard.CloseClipboard()

filepath = 'Ico2.png'
image = Image.open(filepath)

output = BytesIO()
image.convert("RGB").save(output, "BMP")
data = output.getvalue()[14:]
output.close()

send_to_clipboard(win32clipboard.CF_DIB, data)
Luis Villamil
  • 126
  • 1
  • 3
5

For those who want to copy-paste

# parameter must be a PIL image 
def send_to_clipboard(image):
    output = BytesIO()
    image.convert('RGB').save(output, 'BMP')
    data = output.getvalue()[14:]
    output.close()

    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardData(win32clipboard.CF_DIB, data)
    win32clipboard.CloseClipboard()
canbax
  • 3,432
  • 1
  • 27
  • 44
3

With those imports above, a masterpiece

def send_to_clipboard(clip_type, filepath):
    
    image = Image.open(filepath)

    output = BytesIO()
    image.convert("RGB").save(output, "BMP")
    data = output.getvalue()[14:]
    output.close()

    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardData(clip_type, data)
    win32clipboard.CloseClipboard()

send_to_clipboard(win32clipboard.CF_DIB, 'imagem.png')
Joao Victor
  • 509
  • 5
  • 10
2

This is a working app to grab part of the screen as images, once you click on the yellow button it appears in a window made with tkinter, you have to click on top left and then bottom down of an imaginary rectangle that will be the portion of the screen captured. Once you clicked ont the bottom down part of this imaginary rectangle the portion of the screen will be captured. Now open some app like work and press control + v to see the image that has been copied pasted on the app.

# grabscreen.py

import pyscreenshot as ImageGrab
import os
from pynput.mouse import Listener
import sys
import tkinter as tk
from PIL import Image

from io import BytesIO
import win32clipboard


''' Derives from my script grab (use this to show text in a pic and
transform in audio)


'''

def send_to_clipboard(clip_type, data):
    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardData(clip_type, data)
    win32clipboard.CloseClipboard()

def grab(x, y, w, h):
    im = ImageGrab.grab(bbox=(x, y, w, h))
    im.save('im.png')
    image = Image.open("im.png")
    output = BytesIO()
    image.convert("RGB").save(output, "BMP")
    data = output.getvalue()[14:]
    output.close()
    send_to_clipboard(win32clipboard.CF_DIB, data)


click1 = 0
x1 = 0
y1 = 0
def on_click(x, y, button, pressed):
    global click1, x1, y1, listener
    
    if pressed:
        if click1 == 0:
            x1 = x
            y1 = y
            click1 = 1
        else:
            grab(x1, y1, x, y)
            listener.stop()
            sys.exit()
def start():
    global listener

    # root.destroy()
    print("Click once on top left and once on bottom right")
    # with Listener(on_move=on_move, on_click=on_click, on_scroll=on_scroll) as listener:
    with Listener(on_click=on_click) as listener:
        listener.join()
        # listener.stop()
        # sys.exit()

root = tk.Tk()
root.geometry("400x200")
'''
when you click on this button goes to start
in start there i a listener and when you click it sends you to on_click
in on_click it makes you click twice and then goes to grab
in grab it uses pyscreenshot functions to grab the image and save it
we do not use ocr here, to do it use the grab.py file
'''
but = tk.Button(root, text="GRAB GET IMAGE", command=start, width=20,height=10, bg="gold")
but.pack()

root.mainloop()

See ya

PythonProgrammi
  • 22,305
  • 3
  • 41
  • 34
  • check my blog, I got a version that uses pygame to see what you are selecting and copying and you can make different grabbing and at the end it gives you a pdf with all images – PythonProgrammi Mar 28 '22 at 05:13
1

You can copy bitmap image to clipboard using winclip32 install:

pip install winclip32

copy:

import winclip32
winclip32.set_clipboard_data(winclip32.BITMAPINFO_STD_STRUCTURE, your_binary_here)
pypcdev
  • 11
  • 1
0

You can use the Pillow library to copy image to clipboard in Python 3. Here is an example code that takes an image file and copies it to clipboard:

from PIL import ImageGrab, Image

# Open the image file
img = Image.open('image.png')

# Copy the image to the clipboard
img.convert('RGB').toclipboard()

This code opens the image file 'image.png' using the PIL library. It then converts the image to RGB format and copies it to the clipboard using the 'toclipboard()' function.

Note that you need to have the pillow library installed to use this code. You can install it using pip:

pip install pillow
PB LM
  • 9
  • 1