Question

Je souhaite utiliser la bibliothèque Leptonica dans mon application iOS pour traiter les images.

Quelqu'un sait-il comment puis-je créer UIImage à partir des données brutes dans Leptonica 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;

?

Merci!

Était-ce utile?

La solution

Tout d'abord, vous voudrez peut-être vérifier: Convertir l'objet Leptonica Pix en qPixMap (ou autre objet image)

Ce que nous voulons, c'est trouver des formats communs que PIX et UIImage prennent en charge, convertissent de PIX à ce format commun, puis convertissent du format commun en UIImage.

En regardant la bibliothèque Leptonica, il semble que les formats pris en charge sont GIF, JPEG, TIFF, BMP et PNG. JPEG sera avec perte, et GIF et PNG entraîneront tous deux des travaux supplémentaires par le CPU (il y aura un cycle d'encodage / décodage supplémentaire lorsque nous nous convertirons de PIX en UIImage). Pour ces raisons, j'ai choisi TIFF dans l'exemple ci-dessous. Si cela ne fonctionne pas, j'irais avec PNG.

Le plan est le suivant:

  • 1) Convertir de Pix en tampon d'octet
  • 2) Prenez le tampon d'octets et stockez-le dans un nsdata
  • 3) transmettre ces données dans nsimage

Il semble que la fonction PixWriteMem () soit ce dont nous avons besoin pour # 1 (à condition que la prise en charge de lui ait été compilée dans la bibliothèque).

En regardant l'exemple de code inclus avec la bibliothèque, il semble que nous sommes responsables de la libération de la sortie de PixWriteMem () - par conséquent, nous passerons oui dans l'argument Freewhendone: NSDATA.

Quelque chose comme ça (avertissement: code non testé):

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

Autres conseils

Écriture dans un format de fichier intermédiaire. Et la lecture est une méthode simple mais inefficace pour se convertir d'une structure de données en mémoire PIX en une structure de données UIImage (ou tout autre des nombreux conteneurs pour les images en mémoire).

Il est particulièrement inefficace par calcul si la représentation des fichiers intermédiaires est compressée (par exemple, PNG), car les données d'image doivent subir une compression avant de l'écrire et une décompression à un raster non compressé après l'avoir lu.

La méthode efficace pour convertir un struct pix à un struct x est de remplir les champs de métadonnées dans X (la taille de l'image, la profondeur, la résolution, le texte, etc.), génèrent un colormap pour struct x si l'image est colorAP, et convertir les données raster d'image de la convention PIX à la convention x. Ce dernier est la seule partie délicate, car vous devez considérer ce qui suit pour chacune des deux représentations raster en mémoire:

(1) rembourrage pour les lignes raster (la pix est rembourrée à 4 octets)
(2) stockage de pixels multi-composants (Pix stocke chaque composant séquentiellement dans chaque pixel)
(3) taille de pixels à 3 composants, tels que RVB (PIX utilise 4 octets: RGBA)
(4) Ordre d'octets pour les pixels multi-octets (PIX utilise des macros qui déterminent l'ordre des octets RGBA)
(5) Pixel Order: pour Pix, de gauche à droite dans l'image, ils sont stockés dans l'ordre du MSB au LSB dans chaque mot 32 bits

Une spécification pour Struct Pix est donnée dans le fichier Leptonica SRC Pix.h.

Ici, une implémentation (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;
}

Si vous souhaitez convertir 1 image BPP (seuil pour Exapmle)

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

    UIImage *image = [self imageFromPix:pix32];

    pixDestroy(&pix32);

    return image;
}

Il y a une implémentation pour la conversion entre les objets UIImage et PIX dans le repo Tesseract-OCR-IOS.

Voir les méthodes suivantes dans G8Sesseract.m:

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top