在 NSImage 和 Leptonica Pix 之间转换

Posted

技术标签:

【中文标题】在 NSImage 和 Leptonica Pix 之间转换【英文标题】:convert between NSImage and Leptonica Pix 【发布时间】:2012-12-17 22:37:07 【问题描述】:

我正在开发一个 Cocoa OS X 程序来清理扫描的页面,并希望使用 Leptonica's library 来完成繁重的工作。我在this post、this one 和this one 中找到了一些信息。我当然可以从 NSImage 获得 CGImage 并且可以将数据写入 Leptonica Pix 图像。我遇到的问题是,在 75% 的情况下,我的图像以理发店杆型图案扭曲(从图像顶部到底部的每一连续像素行向右移动得越来越远)。有时虽然图片出来很好。我认为我在设置图像数据时做错了,但这并不是我的强项,所以我无法理解这个问题。我正在使用以下代码创建 Pix 图像:

CGImageRef myCGImage = [processedImage CGImageForProposedRect:NULL context:NULL hints:NULL];
CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(myCGImage));
const UInt8 *imageData = CFDataGetBytePtr(data);

Pix *myPix = (Pix *) malloc(sizeof(Pix));
myPix->w = (int)CGImageGetWidth (myCGImage);
myPix->h = (int)CGImageGetHeight (myCGImage);
myPix->d = (int)CGImageGetBitsPerPixel(myCGImage);
myPix->wpl =  ((CGImageGetWidth (myCGImage)*CGImageGetBitsPerPixel(myCGImage))+31)/32;
myPix->informat = IFF_TIFF;
myPix->data = (l_uint32 *) imageData;
myPix->colormap = NULL;

pix 结构体定义如下:

/*-------------------------------------------------------------------------*
 *                              Basic Pix                                  *
 *-------------------------------------------------------------------------*/
struct Pix

uint32             w;           /* width in pixels                   */
uint32             h;           /* height in pixels                  */
uint32             d;           /* depth in bits                     */
uint32             wpl;         /* 32-bit words/line                 */
uint32             refcount;    /* reference count (1 if no clones)  */
int              xres;        /* image res (ppi) in x direction    */
                                  /* (use 0 if unknown)                */
int              yres;        /* image res (ppi) in y direction    */
                                  /* (use 0 if unknown)                */
int              informat;    /* input file format, IFF_*          */
char                *text;        /* text string associated with pix   */
struct PixColormap  *colormap;    /* colormap (may be null)            */
uint32            *data;        /* the image data                    */
;

【问题讨论】:

【参考方案1】:

“理发店杆式模式”是每行像素数据的字节数错误的典型标志。

您应该将wpl 建立在CGImageGetBytesPerRow 返回的值上。最有可能:

myPix->wpl = CGImageGetBytesPerRow(myCGImage) / 4;

图像的每行字节数与您基于CGImageGetWidth() 的猜测不同的原因有多种。例如,出于性能原因,它可能会被四舍五入,或者图像可能是更宽图像的子图像。

【讨论】:

它也可能不是 8-bit-per-component RGBA。它可以使用浮点分量、16 位整数分量,或者在不同的颜色空间中,或者它们的某种组合。某些组合甚至可以为您提供非 RGBA 的 4 字节像素(例如,8 位 CMYK 和浮点灰度),因此您不会得到理发杆图案,但您的输出看起来会很奇怪。

以上是关于在 NSImage 和 Leptonica Pix 之间转换的主要内容,如果未能解决你的问题,请参考以下文章

Leptonica在VS2010中的编译及简单使用举例

NSImage 标准图稿和图标 NSImageNameStatusAvailable

扫描名片Tesseract和Leptonica iOS

扫描名片 Tesseract 和 Leptonica iOS

Ubuntu 16.04 安装 Leptonica 1.75.3

如何防止 PDFKit/NSImage 中的渲染伪影?