2012-01-26 6 views
0

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

Кто-нибудь знает, как я могу создать UIImage из необработанных данных в Pix структуре Leptonica в:

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

?

Спасибо!

ответ

0

Во-первых, вы можете проверить: Convert Leptonica Pix Object to QPixmap (or other image object)

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

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

План заключается в следующем:

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

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

От взгляда на код примера, который входит в библиотеку, похоже, что мы ответственны за освобождение вывода pixWriteMem() - следовательно, мы передадим YES в аргумент freeWhenDone: NSData.

Что-то вроде этого (предупреждение: непроверенный код):

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; 
} 
+0

спасибо за ваш ответ. Тем не менее, похоже, что моя версия Leptonica скомпилирована без поддержки функций «pixWrite ...». Правильно ли, чтобы скомпилировать его с поддержкой этих функций, я должен сделать что-то вроде './configure --with-libtiff = ../libtiff/out', а затем перекомпилировать его? – mym

+0

Да, похоже, вам нужно будет переконфигурировать с помощью libtiff. Однако, прочитав README в Leptonica: «Leptonica также позволяет осуществлять ввод/вывод изображений с форматами bmp и pnm, для которых мы предоставляем сериализаторы ...», поскольку UIImage initWithData: должен поддерживать BMP, вы можете попробовать это и посмотреть, работает. Измените IFF_TIFF на IFF_BMP и посмотрите, что произойдет – iccir

+0

Это очень странно, но кажется, что на платформах i386 и armv7 эта функция не реализована - она ​​показывает ошибку «Ошибка в pixWriteMemBmp: bmp write to memory, не реализованная на этой платформе». – mym

0

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

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

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

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

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

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 изображения (пороги для exapmle)

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

    UIImage *image = [self imageFromPix:pix32]; 

    pixDestroy(&pix32); 

    return image; 
}