Python剪切板提取、截圖、圖片粘貼,操作匯總


1. PIL::ImageGrab(不適用於Linux)

只適用於Windows & MacOS系統。Linux系統支持XCB的X11,詳細說明

1.1. 截圖Grab

  • ImageGrab.grab() ⇒ image: 截全屏
  • ImageGrab.grab(bbox) ⇒ image: 截區域
>>> im = ImageGrab.grab()
>>> im.size
(1366, 768)

>>> im2 = ImageGrab.grab((300, 100, 1400, 600))
>>> im2.mode
'RGB'

1.2. Grabclipboard

截至v7.1.2,尚不支持Linux系統,官網API說明

  • ImageGrab.grabclipboard() ⇒ image or list of strings or None

含義:抓取當前剪貼板的快照,返回一個模式為“RGB”的圖像或者文件名稱的列表。如果剪貼板不包括圖像數據,這個函數返回空。

用戶可以使用函數 isinstance() 來檢查該函數返回的是一個有效圖像對象或者其他數據。

from PIL import Image, ImageGrab

im = ImageGrab.grabclipboard()

if isinstance(im, Image.Image):
    print "Image: size : %s, mode: %s" % (im.size, im.mode)
    im.save("D:\\Document\\mdoc\\python\\pic\\12\\grab_grabclipboard.jpg")
elif im:
    for filename in im:
        try:
            print "filename: %s" % filename
            im = Image.open(filename)
        except IOError:
            pass #ignore this file
        else:
            print "ImageList: size : %s, mode: %s" % (im.size, im.mode)
else:
    print "clipboard is empty."

1.2.1. Error: 'NoneType' object has no attribute 'save'

官方文檔有說明,grabclipboard() 函數有一個緩存的問題,操作太快,有時候它就會讀取上一次的內容,因為第一個沒有讀取到圖像,所以報錯了。

所以解決方案也很簡單,既然是操作太快導致讀取了緩存,那就讓它慢一點唄,我們加上一個時間的延遲就可以了: time.sleep(0.1)

2. MSS: 多屏截屏工具

MSS stands for Multiple Screen Shots.

2.1. 安裝

You can install it with pip:

python -m pip install -U --user mss

Or you can install it with conda:

conda install -c conda-forge python-mss

2.2. 使用

結合PIL使用。

import mss
from PIL import Image


with mss.mss() as sct:
    # Get rid of the first, as it represents the "All in One" monitor:
    for num, monitor in enumerate(sct.monitors[1:], 1):
        # Get raw pixels from the screen
        sct_img = sct.grab(monitor)

        # Create the Image
        img = Image.frombytes("RGB", sct_img.size, sct_img.bgra, "raw", "BGRX")
        # The same, but less efficient:
        # img = Image.frombytes('RGB', sct_img.size, sct_img.rgb)

        # And save it!
        output = "monitor-{}.png".format(num)
        img.save(output)
        print(output)

3. pyscreenshot: 截圖工具

其目標是,適配多種backend,表現為 PIL.ImageGrab 的調用形態。

import pyscreenshot as ImageGrab
im = ImageGrab.grab()
im2 = np.asanyarray(im)

4. pyperclip

pyperclip只支持文本內容,windows下不依賴其它第三方庫,非常輕量易用。

pip install pyperclip

使用示例

>>> import pyperclip

>>> dd = pyperclip.paste()
>>> print(dd)
python大法好!

>>> pyperclip.copy("docs.python.org")
>>> pyperclip.paste()
'docs.python.org'

5. 調用其他程序實現

目前Linux和Mac,對剪切板的操作原生支持還不是很完善(說白了,就是不行……),而且如果不是自己寫腳本的話很難原生支持剪切板里的圖片讀取和寫入。

5.1. MacOS for text

自帶 pbcopypbpaste 工具。

# 寫入剪切板
$ echo 'hihihi' | pbcopy
#或
$ pbcopy < echo 'hello'

# 讀取剪切板
$ pbpaste
# 保存剪切板內容到文件
$ pbpaste > ~/test.txt

5.2. MacOS::pngpaste

目前沒有原生支持剪切板的文字之外的類型。所以必須要下載第三方應用。

pngpaste : 最簡單的剪切板圖像轉文件工具.

  • 不支持直接在文件上ctrl+c這樣拷貝來的圖片
  • 不支持gif

5.3. xclip

原本是在linux常用的剪切板操控工具,后來可能流行起來在mac也支持了。

粘貼圖片的關鍵在於 -t 選項:

  1. See what targets are available:

    $ xclip -selection clipboard -t TARGETS -o
    TARGETS
    image/png
    text/html
    
  2. Note the image/png target; go ahead and get it:

    $ xclip -selection clipboard -t image/png -o > /tmp/avatar.png
    $ see /tmp/avatar.png    # yep, that's it
    

不過,令人郁悶的是,在我的 Xubuntu20.04 中,xclip(v0.13)並不支持 image/png ,原因未知。

額,是支持的——原來這個命令是動態檢測當前剪切板內容的格式,而不是靜態測試所有支持的類型。先復制一張圖片,就可以看到打印出了 image/png 項。

具體使用方法,可以參考以下代碼:

import subprocess

CMD_XCLIP = {
    "has_jpg"   : "xclip -selection clipboard -t TARGETS -o | grep image/jpeg",  # .split()
    "has_png"   : "xclip -selection clipboard -t TARGETS -o | grep image/png",
    "has_txt"   : "xclip -selection clipboard -t TARGETS -o | grep text/plain;charset=utf-8",
    "save_jpg"  : "xclip -selection clipboard -t image/jpeg -o > ",
    "save_png"  : "xclip -selection clipboard -t image/png -o > ",
    "get_txt"   : "xclip -selection clipboard -t text/plain -o",
}

def call_xclip(file_name):

    def run_shell(key, path_save=None):
        str_cmd = CMD_XCLIP[key]
        if path_save:
            str_cmd += path_save
        proc = subprocess.run(str_cmd,
                               shell=True,
                               # stdin=subprocess.PIPE,
                               stdout=subprocess.PIPE)
        return proc.stdout

    if run_shell("has_jpg"):  # != b"":
        run_shell("save_jpg", file_name)
        return b"img\n"

    elif run_shell("has_png"):
        run_shell("save_png", file_name)
        # 格式轉換
        subprocess.call("mogrify -format jpg {}".format(file_name), shell=True)
        return b"img\n"

    elif run_shell("has_txt") != b"":
        txt = run_shell("get_txt")
        return   # bytes

    return b"err\n"

5.4. gpaste

github

看上去很強大(支持剪切板圖片操作),直接使用 apt install gpaste 就可以成功安裝了,還提供了libgpaste-dev用於功能調用。

安裝之后,系統會提供一個 gpaste-daemon 的后台進程,而用戶則是調用 gpaste-client 客戶端實現操作。

不過……我的Xubuntu系統環境下,似乎對該程序的支持並不友好。

5.5. parcellite

github

同樣是使用GTK+開發的剪切板工具。直接使用 sudo apt install parcellite 安裝即可使用。

  • 支持編輯剪切板
  • 全局快捷鍵
  • 不支持圖像的處理
  • 支持自定義Action

一款中規中矩的產品,但運行比較穩定,不會出什么岔子。

6. 終極解決方案

6.1. Qt5

from PyQt5.QtWidgets import QApplication

cb = QApplication.clipboard()
if cb.mimeData().hasImage():
    qt_img = cb.image()
    pil_img = Image.fromqimage(qt_img)  # 轉換為PIL圖像
    pil_img.save(path, "PNG")

6.2. GTK

import gtk

clipboard = gtk.clipboard_get()
image = clipboard.wait_for_image()
if image is not None:
    image.save(fname, "png")


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM