将 Leptonica Pix 对象转换为 QPixmap (或其他图像对象)

发布于 2024-12-23 07:06:56 字数 1889 浏览 6 评论 0原文

我正在使用 Leptonica 库来处理一些图片。之后我想在我的 QT GUI 中显示它们。 Leptonica 使用他们自己的图像格式 Pix,而 QT 使用他们自己的格式 QPixmap。目前,对我来说唯一的方法是在处理后将图片保存为文件(如 bmp ),然后通过 QT 函数调用再次加载它们。现在我想在我的代码中转换它们,所以我不需要绕道将它们保存在文件系统上。有什么想法如何做到这一点?

最好的祝福

// 编辑:

好的,正如已经建议的那样,我尝试将 PIX* 转换为 QImage。 PIX* 定义如下:

http://tpgit.github.com/Leptonica/pix_8h_source.html

struct 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,但实际上我不知道如何?我需要循环遍历所有坐标吗?如何看待位深度?这里有什么想法吗?

I'm using the Leptonica Library to process some pictures. After that I want to show them in my QT GUI. Leptonica is using their own format Pix for the images, while QT is using their own format QPixmap. At the moment the only way for me is to save the pictures after processing as a file ( like bmp ) and then load them again with a QT function call. Now I want to convert them in my code, so I dont need to take the detour with saving them on the filesystem. Any ideas how to do this?

Best Regards

// edit:

Okay as already suggested I tried to convert the PIX* to a QImage.
The PIX* is defined like this:

http://tpgit.github.com/Leptonica/pix_8h_source.html

struct 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                    */
};

while QImage offers me a method like this:

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 )

I assume I cant just copy the data from the PIX to the QImage when calling the constructor. I guess I need to fill the QImage Pixel by Pixel, but actually I dont know how? Do I need to loop through all the coordinates? How do I regard the bit depth? Any ideas here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

め可乐爱微笑 2024-12-30 07:06:56

我使用将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();
}

I use this for conversion QImage to 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);
}

And this for conversion PIX to 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();
}
烙印 2024-12-30 07:06:56

此代码接受 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());
}

This code accepts a const QImage& parameter.

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());
}
请爱~陌生人 2024-12-30 07:06:56

我不知道 Leptonica 库,但我简单浏览了一下文档,找到了有关 的文档PIX结构。您可以从原始数据创建 QImage并将其转换为 QPixmap convertFromImage

I do not know the Leptonica Library, but I had a short look at the documentation and found the documentation about the PIX structure. You can create a QImage from the raw data and convert this to a QPixmap with convertFromImage.

溇涏 2024-12-30 07:06:56

好吧,我可以这样解决问题:

Leptonica 提供了一个函数

l_int32     pixWriteMemBmp (l_uint8 **pdata, size_t *psize, PIX *pix)

,使用这个函数你可以写入内存而不是文件流。尽管如此(在本例中)Bmp 标头和格式仍然存在(其他图像格式也有相同的功能)。

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

这实际上对我有用,但我不知道是否有一种方法可以如此简单地向后执行此操作。 (如果有,请告诉我)

最好的问候

Well I could solve the problem this way:

Leptonica offers a function

l_int32     pixWriteMemBmp (l_uint8 **pdata, size_t *psize, PIX *pix)

With this function you can write into the memory instead of a filestream. Still ( in this example ) the Bmp Header and format persists ( there are the same functions for other image formats too ).

The corresponding function from QT is this one:

bool QImage::loadFromData ( const uchar * data, int len, const char * format = 0 )

Since the the Header persits I just need to pass the data ptr and the size to the loadFromData function and QT does the rest.

So all together it would be like this:

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

This actually works for me, tho I don't know if there is a way to do this backwards so easy. ( If there is, please let me know )

Best Regards

月寒剑心 2024-12-30 07:06:56

您可以将像素图保存到 RAM 而不是文件(使用 QByteArray 来存储数据,使用 QBuffer 作为 I/O 设备)。

You can save your pixmap to RAM instead of file (use QByteArray to store the data, and QBuffer as your I/O device).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文