You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

求Win32gui屏幕截图代码的Linux/Mac OS替代库方案

Cross-Platform Screenshot Solutions (Replacing Win32gui/Win32api)

Hey there! I understand you're migrating your Windows-specific screenshot code (using win32gui/win32api) to Linux and macOS for an external project. Below are practical, Python-based solutions that mirror your original functionality—including cross-platform options and platform-specific tools tailored for better performance or native integration.


1. Cross-Platform Universal Option: PyQt5/PySide2

If you want a single codebase that works on all three platforms (Windows, Linux, macOS), using Qt's screen-grabbing APIs is a solid choice. It supports both full-screen and region-specific captures, just like your original code.

Example Code:

from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QScreen
import sys
import numpy as np
import cv2

def grab_screen(region=None):
    # Ensure we have a valid QApplication instance
    app = QApplication(sys.argv) if not QApplication.instance() else QApplication.instance()
    
    screen = QApplication.primaryScreen()
    if region:
        left, top, x2, y2 = region
        width = x2 - left + 1
        height = y2 - top + 1
        # Capture specified region
        pixmap = screen.grabWindow(0, left, top, width, height)
    else:
        # Capture entire screen
        pixmap = screen.grabWindow(0)
    
    # Convert Qt pixmap to OpenCV-compatible format
    img = pixmap.toImage()
    img_buffer = img.bits().asstring(img.byteCount())
    img_np = np.frombuffer(img_buffer, dtype=np.uint8).reshape(img.height(), img.width(), 4)
    # Convert BGRA to RGB (matches your original code's output)
    return cv2.cvtColor(img_np, cv2.COLOR_BGRA2RGB)

Setup:

Install the Qt bindings with:

pip install pyqt5
# Or use PySide2 if you prefer: pip install pyside2

2. Linux-Specific Solutions

For Linux, you can use lightweight system tools or Python wrappers that integrate seamlessly with desktop environments.

Option A: Use Scrot (System Command)

Scrot is a fast, command-line screenshot tool that's pre-installed on many Linux distros. You can call it directly from Python:

import subprocess
import numpy as np
import cv2
import os

def grab_screen(region=None):
    temp_file = "/tmp/screenshot_temp.png"
    if region:
        left, top, x2, y2 = region
        width = x2 - left + 1
        height = y2 - top + 1
        # Capture specified region with scrot
        subprocess.run(["scrot", "-a", f"{left},{top},{width},{height}", temp_file], check=True)
    else:
        # Capture full screen
        subprocess.run(["scrot", temp_file], check=True)
    
    # Read and convert the image
    img = cv2.imread(temp_file)
    os.remove(temp_file)
    return cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

Setup:

Install Scrot if it's not already present:

# Debian/Ubuntu-based systems
sudo apt install scrot

# Fedora/RHEL-based systems
sudo dnf install scrot

Option B: PyScrot (Python Wrapper)

If you prefer a Python-native interface for Scrot, use pyscrot:

from pyscrot import screenshot
import numpy as np
import cv2

def grab_screen(region=None):
    if region:
        left, top, x2, y2 = region
        width = x2 - left + 1
        height = y2 - top + 1
        img = screenshot(region=(left, top, width, height))
    else:
        img = screenshot()
    # Convert to RGB format
    return cv2.cvtColor(np.array(img), cv2.COLOR_BGR2RGB)

Setup:

pip install pyscrot

3. macOS-Specific Solution: Quartz (Native Framework)

On macOS, using the native Quartz framework via pyobjc gives you the best performance and system integration. Note that macOS uses a bottom-left origin for coordinates, so we'll flip the image to match your original code's output.

Example Code:

import Quartz
import numpy as np
import cv2

def grab_screen(region=None):
    main_display = Quartz.CGMainDisplayID()
    if region:
        left, top, x2, y2 = region
        width = x2 - left + 1
        height = y2 - top + 1
        # Define capture region
        rect = Quartz.CGRectMake(left, top, width, height)
    else:
        # Get full screen bounds
        display_rect = Quartz.CGDisplayBounds(main_display)
        rect = display_rect
    
    # Capture the screen
    image_ref = Quartz.CGDisplayCreateImageWithRect(main_display, rect)
    # Extract pixel data
    width = int(Quartz.CGImageGetWidth(image_ref))
    height = int(Quartz.CGImageGetHeight(image_ref))
    pixel_data = Quartz.CGDataProviderCopyData(Quartz.CGImageGetDataProvider(image_ref))
    img_np = np.frombuffer(pixel_data, dtype=np.uint8).reshape(height, width, 4)
    # Clean up resources
    Quartz.CGImageRelease(image_ref)
    # Flip image to match top-left origin (like Windows) and convert to RGB
    img_np = np.flipud(img_np)
    return cv2.cvtColor(img_np, cv2.COLOR_BGRA2RGB)

Setup:

Install pyobjc to access Quartz:

pip install pyobjc

4. Bonus: High-Performance Cross-Platform Option - MSS

If speed is a priority, mss is a dedicated cross-platform screenshot library optimized for fast captures. It's lightweight and has no external dependencies beyond Python.

Example Code:

import mss
import numpy as np
import cv2

def grab_screen(region=None):
    with mss.mss() as sct:
        if region:
            left, top, x2, y2 = region
            # Define monitor region (MSS uses top-left origin)
            monitor = {"top": top, "left": left, "width": x2 - left + 1, "height": y2 - top + 1}
        else:
            # Use the primary monitor (index 1; index 0 is all monitors combined)
            monitor = sct.monitors[1]
        
        # Capture the screen
        img = sct.grab(monitor)
        # Convert to OpenCV-compatible RGB format
        img_np = np.array(img)
        return cv2.cvtColor(img_np, cv2.COLOR_BGRA2RGB)

Setup:

pip install mss

内容的提问来源于stack exchange,提问作者Gurifisu

火山引擎 最新活动