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
usnake
V2EX  ›  Python

为什么用 Python 保存的图片色彩不对呢

  •  
  •   usnake · 2022-12-05 14:34:21 +08:00 · 3064 次点击
    这是一个创建于 718 天前的主题,其中的信息可能已经有所发展或是发生改变。

    draw.text((296,273),字符串,font=font,fill=(77,84,235)) 我这里用的颜色是 BGR(77,84,235)

    cv2.imwrite(r"C:\Users\aaa\Desktop\img\img.png",img) 但是保存以后的颜色是 BGR(84,95,218)

    是那里没写对吗?

    第 1 条附言  ·  2022-12-05 15:10:06 +08:00
    cv2.imshow("",img)
    不保存 imshow 的时候颜色就不对了,应该不是保存质量的问题
    第 2 条附言  ·  2022-12-05 15:20:42 +08:00
    把代码都发上来大家帮我看看呀,不保存,单纯显示的时候颜色就不一样呢

    ```python
    import time
    import cv2
    import random
    from PIL import ImageFont, ImageDraw, Image
    import numpy as np
    bk_img = cv2.imread("back.png")
    fontpath = "pingfangsc-medium.otf"
    font = ImageFont.truetype(fontpath,26)
    img_pil = Image.fromarray(bk_img)
    draw = ImageDraw.Draw(img_pil)

    money = "50,000.00"
    draw.text((296,273),money,font=font,fill=(77,84,235))

    bk_img = np.array(img_pil)
    cv2.imshow("",bk_img)
    cv2.waitKey()
    ```
    yuhangch
        1
    yuhangch  
       2022-12-05 14:40:48 +08:00
    怎么得到的保存后的颜色,显示器的问题?
    usnake
        2
    usnake  
    OP
       2022-12-05 14:43:23 +08:00
    @yuhangch 保存的图片拉到 photoshop 里面用吸管取色的
    novolunt
        3
    novolunt  
       2022-12-05 14:43:36 +08:00
    AI 的回答
    这个问题可能是由于不同的图像处理库使用的颜色顺序不同导致的。在 Python 的 PIL 库中,颜色顺序通常为 RGB ,因此您在使用 PIL 库绘制文字时,颜色应该按照 RGB 的顺序指定。例如,在上面的代码中,您可以按照如下方式修改颜色顺序:

    draw.text((296,273),字符串,font=font,fill=(235,84,77))

    但是,在保存图像时,您使用的是 cv2 库,它使用的颜色顺序是 BGR 。因此,您需要将颜色顺序转换为 BGR ,才能正确保存图像。例如,您可以按照如下方式修改颜色顺序:

    cv2.imwrite(r"C:\Users\aaa\Desktop\img\img.png",img[:,:,::-1])

    这样,您就可以正确保存图像,并且保存后的图像颜色也是正确的。
    dlsflh
        4
    dlsflh  
       2022-12-05 14:46:10 +08:00 via Android   ❤️ 2
    随便在别人帖子下玩 AI 的真恶心。
    coderluan
        5
    coderluan  
       2022-12-05 14:46:18 +08:00
    默认的 imwrite 是有损压缩的,你得设一下 IMWRITE_PNG_XXX 的一个什么属性,自己搜下吧
    usnake
        6
    usnake  
    OP
       2022-12-05 14:46:58 +08:00
    @novolunt RGB 和 BGR 的颜色区别很明显,一个是蓝色一个是红色,但是我这个保存出来的红色比我设定的红色偏暗,不是 BGR 的问题吧
    coderluan
        7
    coderluan  
       2022-12-05 14:47:59 +08:00   ❤️ 1
    @novolunt AI 回答错误。PS:今天站长封了两个 AI 回复了。
    usnake
        8
    usnake  
    OP
       2022-12-05 14:52:58 +08:00
    @coderluan 用了 9 质量 颜色也不对
    cv2.imwrite(r"img.png",img,[int(cv2.IMWRITE_PNG_COMPRESSION),9])
    sivacohan
        9
    sivacohan  
       2022-12-05 14:55:45 +08:00
    cv2.imwrite(filename, data, [cv2.IMWRITE_PNG_COMPRESSION, 0])
    0 是不压缩

    具体看你的版本吧,这个问题我也遇到过,就是保持的时候压缩了。
    sivacohan
        10
    sivacohan  
       2022-12-05 14:57:14 +08:00
    https://docs.opencv.org/4.x/d8/d6a/group__imgcodecs__flags.html#gga292d81be8d76901bff7988d18d2b42acad2548321c69ab9c0582fd51e75ace1d0


    For PNG, it can be the compression level from 0 to 9. A higher value means a smaller size and longer compression time.
    usnake
        11
    usnake  
    OP
       2022-12-05 15:00:48 +08:00
    @sivacohan 用了 0 ,文件确实变大了 10 倍,但是颜色还是和我设定的有偏差
    AyaseEri
        12
    AyaseEri  
       2022-12-05 15:23:32 +08:00
    你的 PS 画布工作在什么色彩空间下呢,是否经过了色彩管理映射呢
    usnake
        13
    usnake  
    OP
       2022-12-05 15:29:54 +08:00
    @AyaseEri RGB 呀
    wangtian2020
        14
    wangtian2020  
       2022-12-05 15:31:03 +08:00
    不写 python ,会不会是 alpha 透明度通道被忽略了
    usnake
        15
    usnake  
    OP
       2022-12-05 15:31:54 +08:00
    ![Snipaste_2022-12-05_15-31-20.jpg]( http://tva1.sinaimg.cn/large/006vnj0bgy1h8syxbbg0tj30q10e6mz0.jpg)
    看起来还是挺明显的吧
    AyaseEri
        16
    AyaseEri  
       2022-12-05 15:34:13 +08:00
    @usnake 什么 RGB ,sRGB 还是 Display P3 ,还是直接读了你显示器设定的 ICC ?如果不太清楚可能你得换个软件取色,PS 自带色彩管理会对输入图像按显示器设定做色彩转换。
    usnake
        17
    usnake  
    OP
       2022-12-05 15:37:44 +08:00
    @AyaseEri 不是,咱现在不保存文件,单纯用 python 的 cv2.imshow 窗口显示看起来颜色就不对呢
    ysc3839
        18
    ysc3839  
       2022-12-05 15:39:06 +08:00
    你是取文字的颜色吗?估计是文字渲染经过了一些处理导致的。因为渲染文字时不是简单地用你指定的颜色去填充,而是会根据形状边缘做一些处理,使得文字观感更好,处理后的颜色就不是原始颜色了。建议试试用指定颜色填充一块矩形区域,取色看看是否一致。
    laqow
        19
    laqow  
       2022-12-05 15:53:07 +08:00
    感觉是 bk_img 带了颜色方案或者是 CMYK 的,导进来以后就把后面的颜色带歪了。
    另外感觉 cv2 自己的 imread 功能不完整,用 PIL 的 open ,save 来导入导出图片
    lookStupiToForce
        20
    lookStupiToForce  
       2022-12-05 16:01:13 +08:00
    op ,你确定你代码的颜色给对了嘛?
    另外建议直接 with Image.open('back.png') as image:...,不要用 bk_img = cv2.imread("back.png") 再 Image.fromarray(bk_img)转换一次,你这转换过去又转换回来极容易出错 /出现颜色转换损失
    最后,经测试 3 楼用的 AI 回答也还是正确的

    '''
    from PIL import Image, ImageDraw, ImageFont
    import cv2
    import numpy as np

    def test():
    image = Image.new('RGB', (100, 100), (255, 255, 255))
    draw = ImageDraw.Draw(image)
    font = ImageFont.load_default()
    draw_text = 'why use Python'
    draw.text((10, 10), draw_text, font=font, fill=(235, 77, 84))

    output_file = 'test.png'
    output_file_2 = 'test_2.png'
    output_file_3 = 'test_3.png'
    output_file_4 = 'test_4.png'
    image.save(output_file)
    cv2.imwrite(output_file_2, np.asarray(image)) # op 原始方法
    cv2.imwrite(output_file_3, cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)) # copliot 给的方法
    cv2.imwrite(output_file_4, np.asarray(image)[:, :, ::-1]) # chatGPT 的方法


    if __name__ == '__main__':
    test()
    '''
    附图


    反正除了 test_2.png ,其他三幅图的颜色都是对的,分毫不差
    lookStupiToForce
        21
    lookStupiToForce  
       2022-12-05 16:02:26 +08:00
    代码换了,用下面的测试
    '''
    from PIL import Image, ImageDraw, ImageFont
    import cv2
    import numpy as np


    def test():
    image = Image.new('RGB', (150, 150), (255, 255, 255))
    draw = ImageDraw.Draw(image)
    font = ImageFont.truetype("calibri.ttf", size=25)
    draw_text = 'why use\n\nPython'
    draw.text((10, 10), draw_text, font=font, fill=(235, 84, 77))

    output_file = 'test.png'
    output_file_2 = 'test_2.png'
    output_file_3 = 'test_3.png'
    output_file_4 = 'test_4.png'
    image.save(output_file)
    cv2.imwrite(output_file_2, np.asarray(image))
    cv2.imwrite(output_file_3, cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR))
    cv2.imwrite(output_file_4, np.asarray(image)[:, :, ::-1])


    if __name__ == '__main__':
    test()
    '''
    usnake
        22
    usnake  
    OP
       2022-12-05 16:31:19 +08:00
    @lookStupiToForce 感谢您的耐心解答,后来我试过了,我的代码和您给的代码都没问题,有问题的是 photoshop ,我用 Photoshop 习惯取色是 RGB235 ,84 ,77 ,但是用 snipaste 桌面取色是 RGB255 ,68 ,68 ,可能是色彩空间有问题。现在问题解决了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2914 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 03:18 · PVG 11:18 · LAX 19:18 · JFK 22:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.