0

我想在我的 iOS 应用程序中使用 Leptonica 库来处理图像。

有谁知道我如何UIImage从 LeptonicaPix结构中的原始数据创建:

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

?

谢谢!

4

4 回答 4

0

写入中间文件格式。并读回,是一种简单但低效的方法,用于从 Pix 内存数据结构转换为 UIImage 数据结构(或内存中图像的许多容器中的任何其他容器)。

如果中间文件表示被压缩(例如 png),则计算效率特别低,因为图像数据在写出之前必须经过压缩,并在读回之后解压缩到未压缩的栅格。

将struct Pix转换为struct X的有效方法是填充 X 中的元数据字段(图像大小、深度、分辨率、文本等),如果图像被颜色映射,则为 struct X 生成颜色映射,然后转换从 Pix 约定到 X 约定的图像栅格数据。最后一个是唯一棘手的部分,因为您需要为两个内存中的光栅表示中的每一个考虑以下内容:

(1) 栅格线的填充(Pix 被填充到 4 个字节)
(2) 多分量像素的存储(Pix 在每个像素内按顺序存储每个分量)
(3) 3 分量像素的大小,例如 rgb(Pix 使用4字节:rgba)
(4)多字节像素的字节顺序(Pix使用确定rgba字节顺序的宏)
(5)像素顺序:对于 Pix,在图像中从左到右,它们从每个 32 位字中的 MSB 到 LSB

leptonica src 文件 pix.h 中给出了 struct Pix 的规范。

于 2012-01-29T00:54:37.903 回答
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 图像(例如阈值)

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

    UIImage *image = [self imageFromPix:pix32];

    pixDestroy(&pix32);

    return image;
}
于 2014-12-17T09:10:40.740 回答
0

首先,您可能想查看:Convert Leptonica Pix Object to QPixmap (or other image object)

我们想要的是找到 Pix 和 UIImage 都支持的通用格式,从 Pix 转换为该通用格式,然后从通用格式转换为 UIImage。

从 Leptonica 库来看,常见的支持格式似乎是 GIF、JPEG、TIFF、BMP 和 PNG。JPEG 将是有损的,而 GIF 和 PNG 都会导致 CPU 的额外工作(当我们从 Pix 转换为 UIImage 时会有额外的编码/解码周期)。由于这些原因,我在下面的示例中选择了 TIFF。如果它不起作用,我会选择PNG。

计划如下:

  • 1) 从 Pix 转换为字节缓冲区
  • 2)获取字节缓冲区并将其存储到 NSData
  • 3) 将该数据传递到 NSImage

看起来 pixWriteMem() 函数是我们 #1 所需要的(前提是对它的支持已编译到库中)。

从库中包含的示例代码来看,看起来我们负责释放 pixWriteMem() 的输出 - 因此,我们将 YES 传递给 NSData 的 freeWhenDone: 参数。

像这样的东西(警告:未经测试的代码):

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;
}
于 2012-01-26T04:15:29.217 回答
0

在 Tesseract-OCR-iOS 存储库中有一个 UIImage 和 Pix 对象之间转换的实现。

请参阅G8Tesseract.m中的以下方法:

于 2017-10-12T12:16:48.673 回答