使用Python将图像复制到MacOS剪贴板

5
我想在Mac OS上将图片(PIL图像)复制到剪贴板。我尝试了许多不同的方法,但大多数Python剪贴板模块(如pyclip或clipboard)都不支持图像。
我找到了一个在Windows上实现此功能的代码,但在Mac上没有。我尝试使用QT,并通过brew安装它,但由于某种原因,brew安装了一个新的Python 3.7.2(我原来是3.7.1),并且搞乱了终端命令,如python和python3。我设法修复了它,但这非常令人沮丧。而且,无论如何我也无法使它工作。
我看到了win32剪贴板的一种方法,但它只适用于Windows。我尝试了各种不同的模块,但它们都不接受图像。我无法想出解决方案,所以我在这里寻求帮助。
一点背景。我正在编写一个应用程序,该应用程序将从剪贴板保存图像并将其保存到文件中。我对此没有问题,但我还希望存储我保存的内容,并随后能够将其拉回到剪贴板中。就像打开上次保存的那样。

在MacOS中的内置Python具有一组与操作系统框架交互的接口库。请尝试在此处查看答案:https://stackoverflow.com/questions/25692010/cant-access-nspasteboard-using-pyobjc - Simon Hibbs
3个回答

5
这个丑陋的小片段可以工作并将"image.jpg"加载到剪贴板中。
#!/usr/bin/env python3

import subprocess

subprocess.run(["osascript", "-e", 'set the clipboard to (read (POSIX file "image.jpg") as JPEG picture)'])

1
它并没有真正起作用。由于某种原因,它只复制了PNG图像的缩略图。我只是将其粘贴到imgur上:https://i.imgur.com/Jy7xPO2.png - irondsd
请再次检查 - 在我的机器上,任何大小的图像都可以正常工作。您可以在终端中使用sips检查图像的大小,例如sips -g all someImage.jpg - Mark Setchell
我已经让它能够使用JPEG图像工作了,但是对于PNG图像,它只上传缩略图。 - irondsd
当我尝试复制PNG时,它无法工作: subprocess.run(["osascript", "-e", 'set the clipboard to (read (POSIX file "/Users/irondsd/Pictures/Screenshots/Screenshot 2019-01-02 17.38.55.7.png") as PNG picture)']) 122:129: 语法错误:期望“,”但找到类名。 (-2741) CompletedProcess(args=['osascript', '-e', 'set the clipboard to (read (POSIX file "/Users/irondsd/Pictures/Screenshots/Screenshot 2019-01-02 17.38.55.7.png") as PNG picture)'], returncode=1) - irondsd
哦!这很奇怪。它可以正常使用JPEGTIFFGIF格式。也许StackOverflow的顶级Applescripter(@vadian)会知道…… - Mark Setchell

1

https://github.com/RhetTbull/textinator/blob/main/src/pasteboard.py中找到了这个解决方案,可以从.png或.tiff文件中复制,类似于osascript的解决方案,但它直接钩入了pyObjC。

from Foundation import NSData
from AppKit import NSPasteboardTypePNG, NSPasteboardTypeTIFF, NSPasteboard

format = "PNG" # (or "TIFF")
filename = "/path/to/image.png"  # set this to filepath where img is saved
pasteboard = NSPasteboard.generalPasteboard()

image_data = NSData.dataWithContentsOfFile_(filename)
if format not in ("PNG", "TIFF"):
  raise TypeError("Invalid format, must be PNG or TIFF")
format_type = NSPasteboardTypePNG if format == "PNG" else NSPasteboardTypeTIFF
pasteboard.clearContents()
pasteboard.setData_forType_(image_data, format_type)

0
Marks的答案对于png文件对我来说不起作用。
但是我找到了一个完美的解决方法: http://web.archive.org/web/20221029163614/http://www.alecjacobson.com/weblog/?p=3816 创建一个名为impbcopy.m的文件,并将以下内容添加进去。
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import <unistd.h>
BOOL copy_to_clipboard(NSString *path)
{
  // https://dev59.com/e03Sa4cB1Zd3GeqPuFB3
  NSImage * image;
  if([path isEqualToString:@"-"])
  {
    // http://caiustheory.com/read-standard-input-using-objective-c 
    NSFileHandle *input = [NSFileHandle fileHandleWithStandardInput];
    image = [[NSImage alloc] initWithData:[input readDataToEndOfFile]];
  }else
  { 
    image =  [[NSImage alloc] initWithContentsOfFile:path];
  }
  // https://dev59.com/O3XYa4cB1Zd3GeqP6XFK#18124824
  BOOL copied = false;
  if (image != nil)
  {
    NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
    [pasteboard clearContents];
    NSArray *copiedObjects = [NSArray arrayWithObject:image];
    copied = [pasteboard writeObjects:copiedObjects];
    [pasteboard release];
  }
  [image release];
  return copied;
}

int main(int argc, char * const argv[])
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  if(argc<2)
  {
    printf("Usage:\n\n"
      "Copy file to clipboard:\n    ./impbcopy path/to/file\n\n"
      "Copy stdin to clipboard:\n    cat /path/to/file | ./impbcopy -");
    return EXIT_FAILURE;
  }
  NSString *path= [NSString stringWithUTF8String:argv[1]];
  BOOL success = copy_to_clipboard(path);
  [pool release];
  return (success?EXIT_SUCCESS:EXIT_FAILURE);
}

编译 gcc -Wall -g -O3 -ObjC -framework Foundation -framework AppKit -o impbcopy impbcopy.m

然后运行 ./impbcopy 路径/到/文件.png


你现在可以在Python中使用这个了:
import subprocess

subprocess.run("impbcopy", "/path/to/file.png")

当添加到您的路径中时,或者直接指定路径

这个回答与Python问题无关。 - zfj3ub94rf576hc4eegm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接