在 Qt 中使用 FreeImage
Using FreeImage with Qt
我有一段 C++/Qt 代码,我想在其中使用 FreeImage 库 (http://freeimage.sourceforge.net/) 加载图像并将最终结果存储在 QImage
中。我知道 Qt 可以直接加载一堆图像格式,但我希望能够直接加载一些 Qt 不支持的格式......我尝试了各种方法让它工作,但是 none他们工作。
在我展示我的一些失败尝试之前,这是对所有尝试都相同的其余函数。下面的代码片段只是复制并粘贴到这个函数中:
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;
None 这些尝试都奏效了。我检查它是否早些时候失败了,但直到最后我获得 NULL 图像时它才 return 任何错误。但是,我不确定我是否以正确的方式思考它......有人知道我可以尝试什么 ideas/hints 吗?
好吧,其实我自己解决了:)
这个解决方案和我上次的尝试有点相似,它涉及将加载的图像保存到内存(确保它是 24 位图像后)和 "acquiring" 内存(仍然是 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 库 (http://freeimage.sourceforge.net/) 加载图像并将最终结果存储在 QImage
中。我知道 Qt 可以直接加载一堆图像格式,但我希望能够直接加载一些 Qt 不支持的格式......我尝试了各种方法让它工作,但是 none他们工作。
在我展示我的一些失败尝试之前,这是对所有尝试都相同的其余函数。下面的代码片段只是复制并粘贴到这个函数中:
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;
None 这些尝试都奏效了。我检查它是否早些时候失败了,但直到最后我获得 NULL 图像时它才 return 任何错误。但是,我不确定我是否以正确的方式思考它......有人知道我可以尝试什么 ideas/hints 吗?
好吧,其实我自己解决了:)
这个解决方案和我上次的尝试有点相似,它涉及将加载的图像保存到内存(确保它是 24 位图像后)和 "acquiring" 内存(仍然是 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);
}