2011-12-28 93 views
0

我正在使用Leptonica庫來處理一些圖片。之後,我想在我的QT GUI中展示它們。 Leptonica使用自己的格式Pix來處理圖像,而QT使用自己的格式QPixmap。目前唯一的方法是將處理後的圖片保存爲文件(如bmp),然後再用QT函數調用再次加載它們。現在我想在我的代碼中將它們轉換,所以我不需要繞道將它們保存在文件系統中。任何想法如何做到這一點?將Leptonica Pix對象轉換爲QPixmap(或其他圖像對象)

問候

//編輯:

沒關係,已經建議我嘗試在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。我想我需要由Pixel填充QImage Pixel,但實際上我不知道如何?我是否需要遍歷所有座標?我如何看待比特深度?這裏的任何想法?

回答

0

嗯,我可以解決這個問題是這樣的:

Leptonica提供了一個功能

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

有了這個功能,你可以寫入到內存,而不是FILESTREAM。仍然(在這個例子中)Bmp頭和格式仍然存在(對於其他圖像格式也有相同的功能)。

從QT相應的功能是這樣的一種:

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

由於頁眉persits我只需要傳遞數據的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 

這實際上對我的作品,儘管我不知道是否有辦法做到這一點向後那麼容易。(如果有,請告訴我)

問候

1

我不知道Leptonica圖書館,但我看了一下文檔並找到了有關PIX結構的文檔。您可以從原始數據創建QImage,並將其轉換爲QPixmap,其格式爲convertFromImage

+0

嗯謝謝你 - 我想這個工作,但實際上我有點困惑 - >看我的問題 – Toby

+0

更新如果你是幸運的,你應該能夠鑄造它使用Pix.data到一個uchar *:reinterpret_cast (Pix.data)。您必須調整QImage構造函數的Format參數(嘗試QImage :: Format_RGB32或QImage :: Format_ARGB32)。如果您不幸運行,則必須首先創建一個大小爲PIX.wpl * h的新緩衝區,並通過從PIX.data中讀取l_uint32並將它們分爲四個字節(對於R,G,B,A)逐字節複製像素值)通過掩蔽和移位。 – hmuelner

+0

哈好吧我知道了 - 做了一點不同(因爲有一個功能可以做交易) - 但仍然,沒有你建議我使用QImage之前使用QPixmap我也許wouldnt找到它! – Toby

5

I use這個轉換的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(); 
} 
0

你可以將你的pixmap保存到RAM而不是文件(使用QByteArray存儲數據,QBuffer作爲你的I/O設備)。

0

該代碼接受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()); 
}