Создать UIImage из пиксельной структуры Лептоники - PullRequest
0 голосов
/ 26 января 2012

Я хочу использовать библиотеку Leptonica в своем приложении для iOS для обработки изображений.

Кто-нибудь знает, как можно создать 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 ]

0 голосов
/ 12 октября 2017

В репозитории Tesseract-OCR-iOS есть реализация для преобразования объектов UIImage и Pix.

См. Следующие методы в G8Tesseract.m :

0 голосов
/ 29 января 2012

Запись в промежуточный формат файла. и считывание обратно - это простой, но неэффективный метод преобразования структуры данных Pix в памяти в структуру данных UIImage (или любой другой из множества контейнеров для изображений в памяти).

Особенно неэффективно в вычислительном отношении, если представление промежуточного файла сжимается (например, png), потому что данные изображения должны подвергаться сжатию перед записью и распаковке в несжатый растр после считывания обратно.

Эффективный метод преобразования struct Pix в struct X заключается в заполнении полей метаданных в X (размер изображения, глубина, разрешение, текст и т. Д.), сгенерируйте цветовую карту для структуры X, если изображение имеет цветовую карту, и преобразуйте растровые данные изображения из соглашения Pix в соглашение X. Эта последняя единственная сложная часть, поскольку для каждого из двух растровых представлений в памяти необходимо учитывать следующее:

(1) Заполнение для растровых линий (Pix дополняется до 4 байтов)
(2) Хранение многокомпонентных пикселей (Pix сохраняет каждый компонент последовательно в каждом пикселе)
(3) Размер 3-компонентных пикселей, например, rgb (Pix использует 4 байта: rgba)
(4) Порядок байтов для многобайтовых пикселей (Pix использует макросы, которые определяют порядок байтов rgba)
(5) Порядок пикселей: для пикселей слева направо на изображении они сохраняются в порядке от MSB до LSB в каждом 32-битном слове

Спецификация для структуры Pix приведена в файле leptonica src pix.h.

0 голосов
/ 17 декабря 2014

Здесь реализация (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;
}
0 голосов
/ 26 января 2012

Во-первых, вы можете проверить: Преобразовать объект Leptonica Pix в QPixmap (или другой объект изображения)

Нам нужно найти общие форматы, которые поддерживают как Pix, так и UIImageпреобразуйте из Pix в этот общий формат, а затем преобразуйте из общего формата в UIImage.

Из библиотеки Leptonica видно, что общие поддерживаемые форматы: GIF, JPEG, TIFF, BMP и PNG,JPEG будет с потерями, а GIF и PNG приведут к дополнительной работе ЦП (будет дополнительный цикл кодирования / декодирования при преобразовании из Pix в UIImage).По этим причинам я выбрал TIFF в приведенном ниже примере.Если это не работает, я бы пошел с PNG.

План следующий:

  • 1) Преобразовать из пикселя в байтовый буфер
  • 2) Возьмите байтовый буфер и сохраните его в NSData
  • 3) Передайте эти данные в NSImage

Похоже, функция pixWriteMem () - это то, что нам нужно для # 1 (при условииэта поддержка была скомпилирована в библиотеку).

Из примера кода, включенного в библиотеку, видно, что мы несем ответственность за освобождение вывода pixWriteMem () - следовательно, мы передадим YES вNSWata's freeWhenDone: аргумент.

Примерно так (предупреждение: непроверенный код):

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;
}
...