【问题标题】:Using FreeImage with Qt在 Qt 中使用 FreeImage
【发布时间】:2018-03-07 06:14:50
【问题描述】:

我有一段 C++/Qt 代码,我想在其中使用 FreeImage 库 (http://freeimage.sourceforge.net/) 加载图像并将最终结果存储在 QImage 中。我知道 Qt 可以直接加载一堆图像格式,但是我希望能够直接加载一些 Qt 不支持的格式……我尝试了各种方法让它工作,但没有一个工作。

在我展示我的一些失败尝试之前,这是对所有这些尝试都相同的其余功能。下面的代码 sn-ps 只是复制粘贴到这个函数中:

QImage load(QString filename) {

    FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(filename.toStdString().c_str(), 0);
    if(fif == FIF_UNKNOWN)
        fif = FreeImage_GetFIFFromFilename(filename.toStdString().c_str());
    if(fif == FIF_UNKNOWN)
        return QImage();

    FIBITMAP *dib = nullptr;
    if(FreeImage_FIFSupportsReading(fif)) {
        dib = FreeImage_Load(fif, filename.toStdString().c_str());
        if(dib == nullptr)
            return QImage();
    } else
        return QImage();

    .... [conversion code comes here] ....

}

我的前两次尝试非常相似。第一个尝试将图像加载到 QImage 中:

    int width  = FreeImage_GetWidth(dib);
    int height = FreeImage_GetHeight(dib);
    int bpp    = FreeImage_GetBPP(dib);
    int size   = width * height * (bpp / 8);

    BYTE *pixels = FreeImage_GetBits(dib);

    QImage img;
    img = img.fromData(pixels, size);
    return img;

第二个做的或多或少相同,但使用 QPixmap:

    int width  = FreeImage_GetWidth(dib);
    int height = FreeImage_GetHeight(dib);
    int bits   = FreeImage_GetBPP(dib);
    int size   = width * height * (bits / 8);

    BYTE *pixels = FreeImage_GetBits(dib);

    QPixmap pix;
    pix.loadFromData(pixels,size);
    return pix.toImage();

我的第三次尝试是尝试让 FreeImage 将图像以 JPEG 格式保存到内存中,然后在构建图像之前将其加载到 QByteArray 中:

    FIMEMORY *stream = FreeImage_OpenMemory();
    FreeImage_SaveToMemory(FIF_JPEG, dib, stream);
    FreeImage_Unload(dib);
    long size = FreeImage_TellMemory(stream);

    QByteArray array = QByteArray::fromRawData((char*)stream->data, size);
    QImage img;
    img.loadFromData(array);
    return img;

这些尝试都不起作用。我检查了它是否较早失败,但直到我获得 NULL 图像时它才返回任何错误。但是,我不确定我是否以正确的方式思考它......有人有任何想法/提示我可以尝试什么吗?

【问题讨论】:

  • 您是否交叉引用了 Qt 支持的 formats 与 freeimage 支持的匹配格式?
  • 这是我最后一次尝试背后的想法,确保将其转换为 JPEG,以便 Qt 绝对可以读取它...无论如何,我现在解决了,请参阅下面的答案 :)

标签: c++ image qt qimage freeimage


【解决方案1】:

好吧,我最终自己解决了它:)

解决方案有点类似于我上次的尝试,它涉及将加载的图像保存到内存(确保它是 24 位图像之后)和“获取”内存(仍然使用 FreeImage),然后可以将其加载到 QByteArray准备好被 QImage 读入:

QImage load(QString filename) {

    // Get image format
    FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(filename.toStdString().c_str(), 0);
    if(fif == FIF_UNKNOWN)
        fif = FreeImage_GetFIFFromFilename(filename.toStdString().c_str());
    if(fif == FIF_UNKNOWN)
        return QImage();

    // Load image if possible
    FIBITMAP *dib = nullptr;
    if(FreeImage_FIFSupportsReading(fif)) {
        dib = FreeImage_Load(fif, filename.toStdString().c_str());
        if(dib == nullptr)
            return QImage();
    } else
        return QImage();

    // Convert to 24bits and save to memory as JPEG
    FIMEMORY *stream = FreeImage_OpenMemory();
    // FreeImage can only save 24-bit highcolor or 8-bit greyscale/palette bitmaps as JPEG
    dib = FreeImage_ConvertTo24Bits(dib);
    FreeImage_SaveToMemory(FIF_JPEG, dib, stream);

    // Free memory
    FreeImage_Unload(dib);

    // Load JPEG data
    BYTE *mem_buffer = nullptr;
    DWORD size_in_bytes = 0;
    FreeImage_AcquireMemory(stream, &mem_buffer, &size_in_bytes);

    // Load raw data into QImage and return
    QByteArray array = QByteArray::fromRawData((char*)mem_buffer, size_in_bytes);
    return QImage::fromData(array);

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多