无法在释放模式下从字节数组加载 QImage

Cannot load QImage from byte array in release mode

在我的应用程序中,我通过 QTcpSocket 从 Android 设备接收 JPEG 格式的图像作为字节数组。

当我在我的开发 PC 上 运行 这个应用程序时,它的工作就像一个魅力(在调试和发布模式下)。但是,我无法从另一台未安装 Qt 的 PC 上的字节数组加载 QImage

我在 Qt 中为我的平台包含了所有 *.dll 文件(Windows x64,msvc_2015_64)并且还安装了 Visual Studio C++ Redistributable 2015。我的应用程序启动正常(doesn '给出一些 *.dll 文件丢失的任何错误)。但是QImage一直是空的。

起初我以为字节数组根本没有被接收,所以我检查了它的大小,发现它被正确接收了。

我正在使用此代码从 uchar 字节加载 QImage

void handleImageBytes(uchar *bytes, qint64 length)
{
    QImage image;
    image.loadFromData(bytes, length, "JPEG");
    emit frameReady(image);
}

我从 QTcpSocket:

接收到这些字节
void handleReadyRead()
{
    if(this->incomingFrameLength==0){
        QString data = this->client->readAll();
        this->incomingFrameLength = data.toInt();
        this->client->write("ok");
        qDebug()<<QString("Received frame length: %1").arg(this->incomingFrameLength);
        return;
    }

    if(this->incomingFrameLength!=0 && this->client->bytesAvailable()<this->incomingFrameLength)
         return;

    uchar* data = (uchar*)malloc(this->incomingFrameLength+256);
    qint64 len = this->client->read((char*)data, this->incomingFrameLength+256);

    qDebug() << QString("Received %1 bytes").arg(len);

    handleImageBytes(data, len);

    this->incomingFrameLength=0;
    this->client->write("received");
    qDebug()<<QString("Received frame of length %1").arg(len);
    free(data);
}

如您所见,首先我收到图像的大小作为字节数组的长度。 然后我等待 QTcpSocket 的缓冲区中接收并准备好所有需要的字节。然后我创建指向具有足够大小的字节数组的指针,将传入字节加载到该数组并从上面调用 handleImageBytes 方法。

这在我的开发 PC 上一切正常(Windows 7 x64,Qt 5.7,msvc_2015_64)。 但是,当我将我的发布代码和所有必需的 *.dll 文件移动到其他未安装 Qt 的 PC 时,从字节数组加载图像不起作用。

如何解决这个问题?

如果它在您的开发系统中工作,那么您可能仍然缺少一些 DLL。不幸的是,Qt 只会针对强制性 DLL 报错,但还有其他的,即插件,它们是可选的,并且某些功能只有在它们存在时才有可能(例如读取某些图像格式)而不显示任何 DLL 缺失 错误。

复制<QTDIR>\plugins\imageformats文件夹(其中<QTDIR>是你的Qt版本的安装路径,例如我的C:\Qt\qt_5_6_1\msvc2010)到你的可执行文件所在的同一目录。请注意调试和发布二进制文件混合在同一个文件夹中,因此只需复制与您的构建配置相对应的那些。

您的项目目录应如下所示:

project\
        project.exe
        Qt5Core.dll
        Qt5Gui.dll
        ...
        imageformats\
                     qgif.dll
                     qico.dll
                     qjpeg.dll
                     ...

Qt VS Add-on 会自动将一些目录添加到路径中,这就是当 运行 来自 IDE 时它不会失败的原因。

注意: 如果您想使用 SVG 图像,您还必须复制 iconengines\qsvgicon.dllQt5Svg.dll