Search code examples
objective-ciosuiimagepix

Create UIImage from Leptonica's Pix structure


I want to use Leptonica library in my iOS app to process images.

Does anybody knows how can I create UIImage from the raw data in Leptonica's Pix structure:

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

?

Thanks!


Solution

  • First, you might want to check out: Convert Leptonica Pix Object to QPixmap ( or other image object )

    What we want is to find common formats that both Pix and UIImage support, convert from Pix to that common format, and then convert from the common format to UIImage.

    From looking at the Leptonica library, it looks like the common supported formats are GIF, JPEG, TIFF, BMP, and PNG. JPEG will be lossy, and GIF and PNG will both result in additional work by the CPU (there will be an additional encode/decode cycle when we convert from Pix to UIImage). For these reasons, I chose TIFF in the example below. If it doesn't work, I would go with PNG.

    The plan is as follows:

    • 1) Convert from Pix to a byte buffer
    • 2) Take the byte buffer and store it into an NSData
    • 3) Pass that data into NSImage

    It looks like the pixWriteMem() function is what we need for #1 (provided that support for it was compiled into the library).

    From looking at the example code included with the library, it looks like we are responsible for freeing the output of pixWriteMem() - hence, we will pass YES into NSData's freeWhenDone: argument.

    Something like this (warning: untested code):

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