1

レプトニカ ライブラリを使用していくつかの写真を処理しています。その後、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 をピクセルごとに塗りつぶす必要があると思いますが、実際には方法がわかりませんか? すべての座標をループする必要がありますか? ビット深度はどのように考慮すればよいですか? ここに何かアイデアはありますか?

4

5 に答える 5

6

これを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();
}
于 2012-04-04T21:27:50.277 に答える
1

レプトニカ ライブラリについては知りませんが、ドキュメントをざっと見てみると、PIX構造に関するドキュメントが見つかりました。生データからQImageを作成し、これを convertFromImage でQPixmapに変換できます。

于 2011-12-28T12:33:16.427 に答える
1

さて、私はこの方法で問題を解決できました:

レプトニカが提供する機能

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 )

ヘッダーが永続するので、データ 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

これは実際に私にとってはうまくいきますが、これを逆に簡単に行う方法があるかどうかはわかりません。(もしあれば教えてください)

よろしくお願いします

于 2011-12-29T09:01:51.783 に答える
0

ピックスマップをファイルではなく RAM に保存できます (QByteArray を使用してデータを保存し、QBuffer を I/O デバイスとして使用します)。

于 2014-05-23T12:17:51.497 に答える