转换Leptonica像素对象到QPixmap(或其他图像对象)
Convert Leptonica Pix Object to QPixmap ( or other image object )
我正在使用Leptonica Library来处理一些图片。之后,我想在我的QT GUI中显示它们。Leptonica使用自己的图像格式Pix,而QT使用自己的格式QPixmap。目前,我唯一的方法是将处理后的图片保存为文件(如bmp),然后用QT函数调用再次加载它们。现在我想在我的代码中转换它们,所以我不需要绕道将它们保存在文件系统中。有什么办法吗?
问好//编辑:
好的,正如已经建议的那样,我尝试将PIX*转换为QImage。PIX*的定义如下:
http://tpgit.github.com/Leptonica/pix_8h_source.htmlstruct Pix
{
l_uint32 w; /* width in pixels */
l_uint32 h; /* height in pixels */
l_uint32 d; /* depth in bits */
l_uint32 wpl; /* 32-bit words/line */
l_uint32 refcount; /* reference count (1 if no clones) */
l_int32 xres; /* image res (ppi) in x direction */
/* (use 0 if unknown) */
l_int32 yres; /* image res (ppi) in y direction */
/* (use 0 if unknown) */
l_int32 informat; /* input file format, IFF_* */
char *text; /* text string associated with pix */
struct PixColormap *colormap; /* colormap (may be null) */
l_uint32 *data; /* the image data */
};
而QImage为我提供了这样一个方法:
http://developer.qt.nokia.com/doc/qt - 4.8 -/- qimage.html # QImage-7
QImage ( const uchar * data,
int width,
int height,
int bytesPerLine,
Format format )
我假设我不能在调用构造函数时将数据从PIX复制到QImage。我想我需要填补的QImage像素逐像素,但实际上我不知道如何?我需要遍历所有坐标吗?我如何看待比特深度?有什么想法吗?
我用它来转换QImage到PIX:
PIX* TessTools::qImage2PIX(QImage& qImage) {
PIX * pixs;
l_uint32 *lines;
qImage = qImage.rgbSwapped();
int width = qImage.width();
int height = qImage.height();
int depth = qImage.depth();
int wpl = qImage.bytesPerLine() / 4;
pixs = pixCreate(width, height, depth);
pixSetWpl(pixs, wpl);
pixSetColormap(pixs, NULL);
l_uint32 *datas = pixs->data;
for (int y = 0; y < height; y++) {
lines = datas + y * wpl;
QByteArray a((const char*)qImage.scanLine(y), qImage.bytesPerLine());
for (int j = 0; j < a.size(); j++) {
*((l_uint8 *)lines + j) = a[j];
}
}
return pixEndianByteSwapNew(pixs);
}
这是用于转换PIX到QImage:
QImage TessTools::PIX2QImage(PIX *pixImage) {
int width = pixGetWidth(pixImage);
int height = pixGetHeight(pixImage);
int depth = pixGetDepth(pixImage);
int bytesPerLine = pixGetWpl(pixImage) * 4;
l_uint32 * s_data = pixGetData(pixEndianByteSwapNew(pixImage));
QImage::Format format;
if (depth == 1)
format = QImage::Format_Mono;
else if (depth == 8)
format = QImage::Format_Indexed8;
else
format = QImage::Format_RGB32;
QImage result((uchar*)s_data, width, height, bytesPerLine, format);
// Handle pallete
QVector<QRgb> _bwCT;
_bwCT.append(qRgb(255,255,255));
_bwCT.append(qRgb(0,0,0));
QVector<QRgb> _grayscaleCT(256);
for (int i = 0; i < 256; i++) {
_grayscaleCT.append(qRgb(i, i, i));
}
if (depth == 1) {
result.setColorTable(_bwCT);
} else if (depth == 8) {
result.setColorTable(_grayscaleCT);
} else {
result.setColorTable(_grayscaleCT);
}
if (result.isNull()) {
static QImage none(0,0,QImage::Format_Invalid);
qDebug() << "***Invalid format!!!";
return none;
}
return result.rgbSwapped();
}
这段代码接受一个const QImage&
参数。
static PIX* makePIXFromQImage(const QImage &image)
{
QByteArray ba;
QBuffer buf(&ba);
buf.open(QIODevice::WriteOnly);
image.save(&buf, "BMP");
return pixReadMemBmp(ba.constData(), ba.size());
}
我不知道Leptonica Library,但是我浏览了一下文档,找到了关于PIX结构的文档。您可以从原始数据创建一个QImage,并使用convertFromImage将其转换为QPixmap .
我可以这样解决这个问题:
Leptonica提供了一个函数
l_int32 pixWriteMemBmp (l_uint8 **pdata, size_t *psize, PIX *pix)
使用这个函数,您可以写入内存而不是文件流。(在这个例子中)Bmp的Header和格式仍然存在(对于其他图像格式也有相同的函数)。
QT对应的函数是:
bool QImage::loadFromData ( const uchar * data, int len, const char * format = 0 )
由于Header访问,我只需要将数据ptr和大小传递给loadFromData函数,QT完成其余的工作。
所以它们合在一起就像这样:
PIX *m_pix;
FILE * pFile;
pFile = fopen( "PathToFile", "r" );
m_pix = pixReadStreamBmp(pFile); // If other file format use the according function
fclose(pFile);
// Now we have a Pix object from leptonica
l_uint8* ptr_memory;
size_t len;
pixWriteMemBmp(&ptr_memory, &size, m_pix);
// Now we have the picture somewhere in the memory
QImage testimage;
QPixmap pixmap;
testimage.loadFromData((uchar *)ptr_memory,len);
pixmap.convertFromImage(testimage);
// Now we have the image as a pixmap in Qt
这实际上对我有效,虽然我不知道是否有一种方法可以这么容易地做到这一点。(如果有,请告诉我)
您可以将像素图保存到RAM而不是文件(使用QByteArray存储数据,并使用QBuffer作为I/O设备)。
- 具有包含其他对象的类的对象创建顺序
- 对于BTreeMap和其他依赖于Ord的东西,是否有等效于C++比较器对象?
- 如何在线程中初始化对象,然后在其他地方使用它?
- 如何在其他类中使用参数化构造函数制作类的对象?
- 当只有一个线程主要使用该对象而其他线程很少使用它时,如何最小化该对象的互斥锁锁定?
- 如何在不使用new的情况下保持在其他对象中创建的对象存活?
- 为什么最后一个推回向量的对象的字段会转移到向量的其他对象?
- 将抽象对象从主线程发送到其他线程
- 通过向构造函数其他对象引用页面来创建对象
- 如何在 opengl 中仅旋转特定对象而不影响其他对象?
- 推断大多数模板对象的参数,但在调用模板函数时对其他对象显式
- 如何定义此"if block"中其他无效输入的值,以便在c ++中将字符串转换为对象?
- 指向用随机指针归档的其他类对象的指针的c++向量
- 访问其他类中多个对象的私有成员向量
- 在另一个 QThread 上运行成员方法时,无法将事件发送到其他线程拥有的对象
- 当我更改其他 Mat 对象时,垫子值会更改
- neak_ptr vs unique_ptr参考 - 传递接口inmand tos to其他对象
- 谷神星求解器:残差函子使用的可变对象是否良好实践?还有什么其他选择
- 如何在其他文件中使用主文件的场景对象
- 修改对象也会修改同一类的所有其他对象