Pregunta

Quiero usar la biblioteca Leptonica en mi aplicación de iOS para procesar imágenes.

¿Alguien sabe cómo puedo crear? UIImage a partir de los datos sin procesar en Leptonica Pix estructura:

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

?

¡Gracias!

¿Fue útil?

Solución

Primero, es posible que desees consultar: Convierta el objeto Leptonica Pix a QPixmap (u otro objeto de imagen)

Lo que queremos es encontrar formatos comunes que admitan Pix y UIImage, convertir de Pix a ese formato común y luego convertir del formato común a UIImage.

Al observar la biblioteca de Leptonica, parece que los formatos comúnmente admitidos son GIF, JPEG, TIFF, BMP y PNG.JPEG tendrá pérdidas, y GIF y PNG supondrán un trabajo adicional para la CPU (habrá un ciclo de codificación/decodificación adicional cuando conviertamos de Pix a UIImage).Por estos motivos, elegí TIFF en el siguiente ejemplo.Si no funciona, usaría PNG.

El plan es el siguiente:

  • 1) Convertir de Pix a un búfer de bytes
  • 2) Tome el búfer de bytes y guárdelo en un NSData
  • 3) Pasa esos datos a NSImage

Parece que la función pixWriteMem() es lo que necesitamos para el n.° 1 (siempre que se haya compilado el soporte para ella en la biblioteca).

Al observar el código de ejemplo incluido con la biblioteca, parece que somos responsables de liberar la salida de pixWriteMem(); por lo tanto, pasaremos YES al freeWhenDone de NSData:argumento.

Algo como esto (advertencia:código no probado):

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

Otros consejos

Escribir en un formato de archivo intermediario.y volver a leer es un método simple pero ineficiente para convertir de una estructura de datos en memoria Pix a una estructura de datos UIImage (o cualquier otro de los muchos contenedores para imágenes en memoria).

Es particularmente ineficiente desde el punto de vista computacional si la representación del archivo intermedio está comprimida (por ejemplo, png), porque los datos de la imagen deben comprimirse antes de escribirlos y descomprimirse en un ráster sin comprimir después de volver a leerlos.

El método eficiente para convertir un estructura foto a un estructura X es completar los campos de metadatos en X (el tamaño de la imagen, la profundidad, la resolución, el texto, etc.), generar un mapa de colores para la estructura X si la imagen tiene un mapa de colores y convertir los datos rasterizados de la imagen de la convención Pix a la convención X.Esta última es la única parte complicada, porque es necesario considerar lo siguiente para cada una de las dos representaciones ráster en memoria:

(1) Relleno para líneas ráster (Pix se rellena a 4 bytes)
(2) Almacenamiento de píxeles de múltiples componentes (Pix almacena cada componente secuencialmente dentro de cada píxel)
(3) Tamaño de píxeles de 3 componentes, como rgb (Pix utiliza 4 bytes:rgba)
(4) Orden de bytes para píxeles de varios bytes (Pix utiliza macros que determinan el orden de bytes rgba)
(5) Orden de píxeles:para Pix, de izquierda a derecha en la imagen, se almacenan en orden desde MSB hasta LSB en cada palabra de 32 bits.

Se proporciona una especificación para la estructura Pix en el archivo src de leptonica pix.h.

Aquí una implementación (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 desea convertir una imagen de 1 bpp (umbral, por ejemplo)

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

    UIImage *image = [self imageFromPix:pix32];

    pixDestroy(&pix32);

    return image;
}

Hay una implementación para la conversión entre objetos UIImage y Pix en el repositorio Tesseract-OCR-iOS.

Consulte los siguientes métodos en G8Tesseract.m:

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top