0

iOSアプリでLeptonicaライブラリを使用して画像を処理したい。

UIImageレプトニカのPix構造の生データからどのように作成できるか知っている人はいますか?

/*-------------------------------------------------------------------------*
 *                              Basic Pix                                  *
 *-------------------------------------------------------------------------*/
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                    */
};
typedef struct Pix PIX;

ありがとう!

4

4 に答える 4

0

中間ファイル形式への書き込み。読み戻しは、Pixのメモリ内データ構造からUIImageデータ構造(またはメモリ内の画像用の多くのコンテナのいずれか)に変換するための単純ですが非効率的な方法です。

中間ファイル表現が圧縮されている場合(たとえば、png)、計算は特に非効率的です。これは、画像データを書き出す前に圧縮し、読み戻した後に非圧縮ラスターに解凍する必要があるためです。

構造体Pix構造体Xに変換する効率的な方法は、Xのメタデータフィールド(画像サイズ、深度、解像度、テキストなど)に入力し、画像がカラーマップされている場合は構造体Xのカラーマップを生成し、 Pix規則からX規則への画像ラスターデータ。この最後の部分は、2つのメモリ内ラスター表現のそれぞれについて次のことを考慮する必要があるため、唯一の注意が必要な部分です。

(1)ラスターラインのパディング(Pixは4バイトにパディングされます)
(2)マルチコンポーネントピクセルのストレージ(Pixは各コンポーネントを各ピクセル内に順番に格納します)
(3)rgbなどの3コンポーネントピクセルのサイズ(Pixは4バイト:rgba)
(4)マルチバイトピクセルのバイト順序(Pixはrgbaバイト順序を決定するマクロを使用します)
(5)ピクセル順序:Pixの場合、画像の左から右に、各32ビットワードのLSBへのMSB

struct Pixの仕様は、leptonicasrcファイルpix.hに記載されています。

于 2012-01-29T00:54:37.903 に答える
0

まず、次のことを確認してください。Leptonica PixオブジェクトをQPixmap(または他の画像オブジェクト)に変換する

私たちが望んでいるのは、PixとUIImageの両方がサポートする一般的な形式を見つけ、Pixからその一般的な形式に変換してから、一般的な形式からUIImageに変換することです。

Leptonicaライブラリを見ると、サポートされている一般的な形式はGIF、JPEG、TIFF、BMP、およびPNGのようです。JPEGは不可逆であり、GIFとPNGはどちらもCPUによる追加の作業をもたらします(PixからUIImageに変換するときに追加のエンコード/デコードサイクルがあります)。これらの理由から、以下の例ではTIFFを選択しました。それがうまくいかない場合は、PNGを使用します。

計画は以下の通りです。

  • 1)Pixからバイトバッファに変換する
  • 2)バイトバッファを取得してNSDataに保存します
  • 3)そのデータをNSImageに渡します

pixWriteMem()関数が#1に必要なもののようです(そのサポートがライブラリにコンパイルされている場合)。

ライブラリに含まれているサンプルコードを見ると、pixWriteMem()の出力を解放する責任があるようです。したがって、NSDataのfreeWhenDone:引数にYESを渡します。

このようなもの(警告:テストされていないコード):

UIImage *GetImageFromPix(Pix *thePix)
{
    UIImage *result = nil;

    l_uint8 *bytes = NULL;
    size_t size = 0;

    if (0 == pixWriteMem(&bytes, &size, thePix, IFF_TIFF)) {
        NSData *data = [[NSData alloc] initWithBytesNoCopy:bytes length:(NSUInteger)size freeWhenDone:YES];
        result = [UIImage imageWithData:data];
        [data release];
    }

    return result;
}
于 2012-01-26T04:15:29.217 に答える
0

ここに実装(32 bpp-> UIImage)

- (UIImage *)imageFromPix:(Pix *)pix
{
    l_uint32 width = pixGetWidth(pix);
    l_uint32 height = pixGetHeight(pix);
    l_uint32 bitsPerPixel = pixGetDepth(pix);
    l_uint32 bytesPerRow = pixGetWpl(pix) * 4;
    l_uint32 bitsPerComponent = 8;
    if (pixSetSpp(pix, 4) == 0) {
        bitsPerComponent = bitsPerPixel / pixGetSpp(pix);
    }

    l_uint32 *pixData = pixGetData(pix);

    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixData, bytesPerRow * height, NULL);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGImage *cgImage = CGImageCreate(width, height,
                                     bitsPerComponent, bitsPerPixel, bytesPerRow,
                                     colorSpace, kCGBitmapByteOrderDefault,
                                     provider, NULL, NO, kCGRenderingIntentDefault);

    CGDataProviderRelease(provider);
    CGColorSpaceRelease(colorSpace);

    UIImage *image = [UIImage imageWithCGImage:cgImage];
    return image;
}

1 bpp画像を変換する場合(例としてしきい値処理)

- (UIImage *)imageFrom1bppPix:(Pix *)pix
{
    Pix *pix32 = pixUnpackBinary(pix, 32, 0);

    UIImage *image = [self imageFromPix:pix32];

    pixDestroy(&pix32);

    return image;
}
于 2014-12-17T09:10:40.740 に答える
0

Tesseract-OCR-iOSリポジトリにUIImageオブジェクトとPixオブジェクト間の変換の実装があります。

G8Tesseract.mの次のメソッドを参照してください。

于 2017-10-12T12:16:48.673 に答える