V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
evemoo
V2EX  ›  Python

win32clipboard 复制 gif 的问题

  •  
  •   evemoo · 2023-02-10 17:07:58 +08:00 · 1398 次点击
    这是一个创建于 657 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如果只是处理 JPG/PNG 格式用以下代码就可以完成任务,配合注册表可以在不打开图片的情况下右键复制图片内容。但在处理 gifimage.save(output, "GiF") 则无输出结果。

    # coding:utf-8
    
    import sys
    import traceback
    import win32clipboard
    
    from io import BytesIO
    from PIL import Image
    
    
    def send_to_clipboard(clip_type, data):
        win32clipboard.OpenClipboard()
        win32clipboard.EmptyClipboard()
        win32clipboard.SetClipboardData(clip_type, data)
        win32clipboard.CloseClipboard()
    
    
    def get_image_data(args):
        image = Image.open(args)
        output = BytesIO()
        image.convert("RGB").save(output, "BMP")
        data = output.getvalue()[14:]  # Bitmap header size
        return data
    
    
    if __name__ == "__main__:
        try:
            data = get_image_data(sys.argv[1])
            send_to_clipboard(win32clipboard.CF_DIB, data)
        except Exception:
        	traceback.print_exc()
    
    

    手动复制一张 gif 图,查看两种图片编码会得到如下结果:

    import chardet
    
    def test():
        try:
            with open("1.gif", "rb") as f:
        	    data = f.read()
        	    print(f"get stream from BytesIO", data[:30])
                print(chardet.detect(data[:30]))
        except Exception as e:
            print(str(e))
            
        try:
        	win32clipboard.OpenClipboard()
            data = win32clipboard.GetClipboardData(win32clipboard.CF_DIB)
            print(f"get stream from windows clipboard", data[:30])
            print(chardet.detect(data[:30]))
        except Exception as e:
            print(str(e))
        finally:
            win32clipboard.CloseClipboard()
    
    get stream from BytesIO b'GIF89aJ\x03T\x02\xf7\xff\x00\\d_+bV\x18\x18\x1c\xd9\xd2\x9du\xa1\'
    {'encoding': 'Windows-1252', 'confidence': 0.73, 'language': ''}
    
    get stream from windows clipboard b'(\x00\x00\x00J\x03\x00\x00T\x02\x00\x00\x01\x00 \x00\x03\x00'
    {'encoding': 'ISO-8859-1', 'confidence': 0.73, 'language': ''}
    

    直接对 BytesIO 输出的数据流进行转码 data[14:].decode("Windows-1252").encode("ISO-8859-1") 也解决不了问题。求解

    References:

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4393 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 10:10 · PVG 18:10 · LAX 02:10 · JFK 05:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.