将 QPixmap 保存为 JPEG 会导致垂直线

发布于 2024-11-30 13:40:48 字数 1320 浏览 1 评论 0原文

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

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

(这实际上应该是一些珠宝)

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

但是,保存图像在服务器和其他客户端上运行良好。

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

Process Explorer 在服务器和问题 PC 上显示应用程序进程的相同 DLL,但问题 PC 使用 dnsapi.dll(服务器不显示)。

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

有什么建议吗?

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

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

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

A user installed our application to a server PC, shared the install directory as network drive Z: and now opens the app from different client PCs all over his shop. Everything works fine except for a naggling bug on one of the PCs:

On the Problem PC, the app can load .jpg files for inventory items just fine and show the corresponding QPixmap in a QLabel. When the inventory item he is currently viewing does not yet have an image assigned to it, he can open a file dialog, choose an image and display that correctly. However, saving the (new/changed) QPixmap as a .jpg stores it to disc as a series of colored vertical lines on a black background:

(this should actually be some jewellery)

Saving is done via QPixmap::save( const QString & fileName, ...) with the file name set programmatically to "<some_id>.jpg" to designate the desired file format. Returns true, but the resulting file looks like modern art.

However, saving images works fine on the server and the other clients.

Both the server and the Problem PC run Windows XP at an identical patch level.

Process Explorer shows identical DLLs for the app process on server and Problem PC except for the Problem PC using dnsapi.dll, which the server doesn't.

Process Explorer also shows that on both server and client the Qt DLL used to deal with JPEGs is
\Device\LanmanRedirector\<server>\<app>\plugins\imageformats\qjpeg4.dll, and a drive-wide search on the Problem PC for qjpeg*.dll came up empty, so the app should use the same JPEG handling code on both computers.

Any suggestions?

(EDIT: added OS and patch status to problem description.)

EDIT: Solution: on the problem machine we had a 16 bpp colour depth. Setting that to 32 bpp solved our problem instantly. I also replaced
_pm.save( sDestFileName )
with
_pm.toImage().convertToFormat( QImage::Format_RGB32 ).save( sDestFileName )
so that we won't run into this on every old client PC running less than 32 bpp.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

带刺的爱情 2024-12-07 13:40:48

以下是尝试隔离问题的一些方法:

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

下面的函数来自我编写的OSS 程序。您可以尝试使用它,然后显示第二个参数中引用的 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;
}

Here are a few things to try to isolate the problem:

  • Copy qjpeg4.dll to the client's working directory
  • Is the image corrupted when saving as PNG or GIF?
  • Convert your data to a QImage and work from that.
  • Consider the byte format (I usually use ARGB32 because it is int-aligned)
  • To test where the problem occurs, you might try converting the image to JPG format then viewing it in a debugging window.

The function below is from an OSS program I wrote. You might try using it then displaying the contents of the QImage referred to in the second parameter:

//! 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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文