PyQt5 - fromIccProfile:最小标签大小完整性错误失败

PyQt5 - fromIccProfile: failed minimal tag size sanity error

我使用的是最新的 PyQt5 5.12.2,对于我在脚本中使用 QPixmap 或 QIcon 显示的每张 JPG 图片,我都收到一条奇怪的消息。

qt.gui.icc: fromIccProfile: failed minimal tag size sanity

它没有引起任何问题,脚本可以正常工作。问题是我试图同时显示大量的 jpg 图片(作为照片库),因此 window 在为每张照片打印所​​有消息之前没有响应。

我尝试了几个小时在网上找到有用的东西,但不幸的是,似乎几乎没有人遇到过同样的问题。我也在使用一些 PNG 文件,它们不会引发此错误,所以我假设问题出在 jpg 格式上。我尝试使用旧的 pyqt5 版本,但唯一的区别是它们没有打印消息,但问题仍然存在。

与此同时,我尝试使用此命令使这些消息静音,因为没有使用它们,但即使控制台未打印,window 几秒钟无响应的问题仍然存在。

def handler(*args):
    pass
qInstallMessageHandler(handler)

编辑:我尝试将这些图像转换为 PNG,但错误仍然存​​在。所以 JPG 格式不是问题

我更深入地研究了 ICC 配置文件和颜色 spaces,看起来你的图片使用的颜色 space 在某种程度上对 PyQt 来说是非标准的。

我的解决方案是将这些图片转换为经典的 ICC 配置文件,例如 sRGB。 这是一个示例函数:

import io
from PIL import Image, ImageCms
def convert_to_srgb(file_path):
        '''Convert PIL image to sRGB color space (if possible)'''
        img = Image.open(file_path)
        icc = img.info.get('icc_profile', '')
        if icc:
            io_handle = io.BytesIO(icc)     # virtual file
            src_profile = ImageCms.ImageCmsProfile(io_handle)
            dst_profile = ImageCms.createProfile('sRGB')
            img_conv = ImageCms.profileToProfile(img, src_profile, dst_profile)
            icc_conv = img_conv.info.get('icc_profile','')
        if icc != icc_conv:
            # ICC profile was changed -> save converted file
            img_conv.save(file_path,
                        format = 'JPEG',
                        quality = 50,
                        icc_profile = icc_conv)

使用 PIL 库是正确解决该错误的快速有效方法。

我正在使用 Pyside2 制作 GUI 图像查看器,并且遇到了类似的问题。 图片加载正常,对于我来说没有性能问题,但我不断收到这些 ICC 警告。 而且我不想修复原始文件,因为我的应用程序应该只是一个查看器。

我不知道这对您的情况是否有帮助,但我的解决方案是首先使用 pillow ImageQT module

加载图像
from pathlib import Path
from PIL.ImageQt import ImageQt

def load_image(path):
    if Path(path).is_file():
        return ImageQt(path)

然后在显示图像的 QT 小部件 class 中,我将此图像加载到空 QPixmap 上:

def on_change(self, path):
    pixmap = QtGui.QPixmap()
    image = load_image(path)
    if image:
        pixmap.convertFromImage(image)
    if pixmap.isNull():
        self.display_area_label.setText('No Image')
    else:
        self.display_area_label.setPixmap(pixmap)