我想在我的iOS应用程序中使用Leptonica库来处理图像。
有人知道如何从Leptonica的UIImage
结构中的原始数据创建Pix
:
/*-------------------------------------------------------------------------*
* 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;
谢谢!
答案 0 :(得分: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。
计划如下:
看起来像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;
}
答案 1 :(得分: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的顺序
struct pix的规范在leptonica src文件pix.h中给出。
答案 2 :(得分: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图像(阈值为exapmle)
- (UIImage *)imageFrom1bppPix:(Pix *)pix
{
Pix *pix32 = pixUnpackBinary(pix, 32, 0);
UIImage *image = [self imageFromPix:pix32];
pixDestroy(&pix32);
return image;
}
答案 3 :(得分:0)
在Tesseract-OCR-iOS仓库中有UIImage和Pix对象之间的转换实现。
请参阅G8Tesseract.m中的以下方法: