c++ - 在 Qt 中使用 FreeImage

标签 c++ image qt qimage freeimage

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

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

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 图像时它才返回任何错误。但是,我不确定我是否以正确的方式思考它......有人有任何想法/提示我可以尝试什么吗?

最佳答案

好吧,其实我自己解决了:)

该解决方案与我上次的尝试有些相似,它涉及将加载的图像保存到内存(确保它是 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);

}

关于c++ - 在 Qt 中使用 FreeImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49137081/

相关文章:

c++ - QLabel::setPixmap() 和 QScrollArea::setWidget()

c++ - 这个功能有什么问题?我哪里弄错了?

javascript - 如何用CSS中的默认图像替换不存在的图像?

css - 滚动到屏幕外的最后一张 float 图像

c++ - Qt中如何编写TLS加密的客户端和服务端?

c++ - QString 在 QVector 内存泄漏

c++ - 自定义 vector 类型

java - Android - 缩放和压缩位图

c++ - 如何使用 Qt 在队列中创建多个线程?

c++ - 从对象 vector 中获取成员 vector