【问题标题】:Saving QPixmap as JPEG results in vertical lines将 QPixmap 保存为 JPEG 会导致垂直线
【发布时间】:2011-08-22 14:21:43
【问题描述】:

用户将我们的应用程序安装到服务器 PC,将安装目录共享为网络驱动器 Z:现在从他商店的不同客户端 PC 上打开应用程序。一切正常,除了其中一台 PC 上的一个棘手的错误:

在问题 PC 上,该应用可以很好地加载库存项目的 .jpg 文件,并在 QLabel 中显示相应的 QPixmap。当他当前正在查看的库存项目还没有分配给它的图像时,他可以打开一个文件对话框,选择一个图像并正确显示它。但是,保存(新的/更改的)QPixmap 为.jpg 将其作为黑色背景上的一系列彩色垂直线存储到磁盘:

通过QPixmap::save( const QString & fileName, ...) 完成保存,文件名以编程方式设置为“<some_id>.jpg”以指定所需的文件格式。返回true,但生成的文件看起来像现代艺术。

但是,保存图像在服务器和其他客户端上工作正常。

服务器和问题 PC 都以相同的补丁级别运行 Windows XP。

进程资源管理器为服务器和问题 PC 上的应用程序进程显示相同的 DLL,除了使用 dnsapi.dll 的问题 PC,服务器没有。

Process Explorer 还显示,在服务器和客户端上,用于处理 JPEG 的 Qt DLL 是 \Device\LanmanRedirector\<server>\<app>\plugins\imageformats\qjpeg4.dll,并且在问题 PC 上对 qjpeg*.dll 的驱动器范围搜索结果为空,因此该应用应该在两台计算机上使用相同的 JPEG 处理代码。

有什么建议吗?

(编辑:在问题描述中添加了操作系统和补丁状态。)

编辑:解决方案:在问题机器上,我们的色深为 16 bpp。将其设置为 32 bpp 立即解决了我们的问题。我也换了
_pm.save( sDestFileName )

_pm.toImage().convertToFormat( QImage::Format_RGB32 ).save( sDestFileName )
这样我们就不会在每台运行低于 32 bpp 的旧客户端 PC 上遇到这种情况。

【问题讨论】:

    标签: c++ qt dll jpeg qpixmap


    【解决方案1】:

    这里有几件事可以尝试隔离问题:

    • 复制qjpeg4.dll到客户端工作目录
    • 保存为 PNG 或 GIF 时图像是否损坏?
    • 将您的数据转换为 QImage 并从中工作。
    • 考虑字节格式(我通常使用 ARGB32,因为它是 int-aligned)
    • 要测试问题出在哪里,您可以尝试将图像转换为 JPG 格式,然后在调试窗口中查看。

    下面的函数来自我写的OSS program。您可以尝试使用它,然后显示第二个参数中引用的 QImage 的内容:

    //! Saves image with JPEG compression in given quality (0 - 100, Qt's scale)
    //! @param[in] in The lossless input image
    //! @param[out] out The image to save to using JPEG compression
    //! @param quality The quality level (0 - 100, 0 the most compressed)
    //! @return The size of the saved image
    quint32 Window::imageSaveLossy(QImage &in, QImage &out, quint8 quality)
    {
            quint32 retval;
            QByteArray ba;
            QBuffer buffer(&ba);
            buffer.open(QIODevice::WriteOnly);
    
            QImage temp(in.size(), QImage::Format_ARGB32);
            temp.fill(QColor(Qt::white).rgb());
            QPainter painter(&temp);
            painter.drawImage(0, 0, in);
    
            temp.save(&buffer, "JPG", quality);
            out.loadFromData(ba, "JPG");
            retval = (quint32)ba.size();
            buffer.close();
            return retval;
    }
    

    【讨论】:

    • 感谢您的建议。让我们看看: 1.) 客户端的工作目录是驱动器 Z:,它是服务器上的安装目录,其中包含带有 qjpeg4.dll 的 plugins\imageformats 目录。 2.) 我将构建一个自定义版本,将图像保存为 .jpg、.png .gif。 3.) QPixmap::save() 自动执行 toImage() 。 4.) 我将研究使用的字节格式。 5.) 我会试试你的小转换器功能,看看输出,谢谢!
    • 好的,半个永恒之后:2.) 保存为 .png 可以正常工作 4.) 字节格式:这很奇怪。显示图像时,QPixmap::depth() 在 P-PC 上返回 16,在服务器上返回 32,默认深度为 32。因此在保存期间转换 pm.toImage() 会导致图像是两倍在服务器上与在 P-PC 上一样大。这值得研究。
    • 在 QPixmap::save() 期间破坏了默认转换的是 16 bpp 的系统范围颜色深度。将 PC 设置为 32 BPP 使其工作。
    猜你喜欢
    • 2010-11-11
    • 1970-01-01
    • 2023-01-16
    • 2016-07-03
    • 2017-10-16
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    相关资源
    最近更新 更多