4

I want to use Leptonica library in my iOS application for image processing and have troubles figuring out how to get Leptonica's Pix structure from UIImage. What I suggest to do is something like the following:

UIImage *image = [UIImage imageNamed:@"test.png"];
...
CFDataRef imageData = CGDataProviderCopyData(CGImageGetDataProvider([image CGImage]));
const UInt8 *rasterData = CFDataGetBytePtr(data);

Can anyone suggest how to correctly convert this data to 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                    */
};

UPD:

I am doing like this:

UIImage *image = [UIImage imageNamed:@"test.png"];

CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider([image CGImage]));
const UInt8 *imageData = CFDataGetBytePtr(data);

Pix *myPix = (Pix *) malloc(sizeof(Pix));

CGImageRef myCGImage = [image CGImage];

myPix->w = CGImageGetWidth (myCGImage);
myPix->h = CGImageGetHeight (myCGImage);
myPix->d = CGImageGetBitsPerComponent(myCGImage);
myPix->wpl = CGImageGetBytesPerRow (myCGImage) / 4;
myPix->data = (l_uint32 *) imageData;
myPix->colormap = NULL;

NSLog(@"pixWrite=%d", pixWrite("/tmp/lept-res.bmp", myPix, IFF_BMP));

But what I get is quite different from the original picture:

http://dl.dropbox.com/u/4409984/so/lept-orig.png

vs.

http://dl.dropbox.com/u/4409984/so/lept-res.png

What am I doing wrong?

mym
  • 252
  • 2
  • 9

2 Answers2

1

Try following code:

CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider([picture CGImage]));
const UInt8 *imageData = CFDataGetBytePtr(data);

Pix *myPix = (Pix *) malloc(sizeof(Pix));
CGImageRef myCGImage = [picture CGImage];

myPix->w = CGImageGetWidth (myCGImage);
myPix->h = CGImageGetHeight (myCGImage);
myPix->d = CGImageGetBitsPerPixel([picture CGImage]) ;
myPix->wpl = CGImageGetBytesPerRow (myCGImage)/4 ;
myPix->data = (l_uint32 *) imageData;
myPix->colormap = NULL;

pixEndianByteSwap(myPix);

NSLog(@"pixWrite=%d", pixWrite("/tmp/lept-res.bmp", myPix, IFF_BMP));
Toto
  • 89,455
  • 62
  • 89
  • 125
Arkadi
  • 56
  • 2
0

Once you have a CGImage, you can get most of that information directly from the CGImage.

CGImageRef myCGImage = [image CGImage];
struct Pix myPix;
myPix.w = CGImageGetWidth (myCGImage);
myPix.h = CGImageGetHeight (myCGImage);
myPix.d = CGImageGetBitsPerComponent (myCGImage);
myPix.wpl = CGImageGetBytesPerRow (myCGImage) / 4;
... etc. ...
user1118321
  • 25,567
  • 4
  • 55
  • 86
  • It's an obvious way, but how to do it correctly? I updated my question with the results I'm getting. What am I doing wrong? – mym Feb 01 '12 at 07:17
  • You probably just need to set the other fields, too. If you know the resolution of your camera, you can use that, or if you have a way to get it from the input image, use that. Otherwise, 72 is a standard default if you don't know it. – user1118321 Feb 01 '12 at 17:54
  • It looks like something's misinterpreting the pixel data, for one thing. I'm not familiar with Leptonica. Does the "d" member of the Pix structure represent bits per pixel or bits per channel? Try multiplying it by 4 and see if that helps. Otherwise, check the documentation to understand the meaning of each field. – user1118321 Feb 01 '12 at 18:46