首先,您是对的,原生 iOS(和 Mac OS)框架确实支持嵌入在 PDF 数据流中的 JBIG2 图像——实际上它是 Core Graphics 的一部分。
在 iOS 中读取图像的公共 API 是ImageIO。它通过添加通用图像文件读取和写入功能来扩展 Core Graphics。它创建CGImage
可以在CGContext
s 中使用的对象来解压缩和渲染。遗憾的是它无法读取 jbig2 图像文件。
另一方面,可以渲染包含 JBIG2 图像的PDF。这似乎可以通过 Core Graphics 向 CGImage 添加自定义过滤器来实现,这些过滤器仅在渲染 PDF 时使用:
> cd /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/Frameworks
> nm -arch armv7 ./CoreGraphics.framework/CoreGraphics | grep jbig2
000f4f6c t _jbig2_create_state
00081e68 t _jbig2_filter_finalize
00081e44 t _jbig2_filter_refill
00081e24 t _jbig2_filter_rewind
000f500c t _jbig2_read_bytes
000f4fc0 t _jbig2_release_state
000f5064 t _jbig2_rewind
0013b78c b _jbig2_vtable
00081d9c t _pdf_source_create_jbig2_filter
001247f0 s _pdf_source_create_jbig2_filter.callbacks
在运行 Instruments 时在 Preview 中显示 PDF 会显示实现 JBIG2 支持的库:
这是实际的库:
> nm -arch armv7 ./CoreGraphics.framework/Resources/libJBIG2.dylib | c++filt
...
00001f68 unsigned short JBIG2Bitmap::JBIG2Bitmap(unsigned int, JBIG2Bitmap*)
00007adc unsigned short JBIG2Stream::readGenericBitmap(int, int, int, int, int, int, JBIG2Bitmap*, int*, int*, int)
...
这个库似乎包含一些xpdf-3代码,但主要是 Apple 的私有实现。这个库没有头文件,所以它被认为是私有的,尤其是在 iOS 上。
这让我们只有一个选择如何使用 iOS 原生 JBIG2 解压缩:您必须将 JBIG2 文件包装成最小的 PDF。我不认为运行时开销是相关的。
附加说明注释:从 PDF 创建图像的代码。这假定 PDF 包含一页,其中包含 72 dpi 的无边界 JBIG2 图像。
// create PDF document
CGPDFDocumentRef document = CGPDFDocumentCreateWithURL((__bridge CFURLRef)[NSURL fileURLWithPath:path]);
// get the first page
CGPDFPageRef page = CGPDFDocumentGetPage(document, 1);
// create a bitmap context
CGSize size = CGPDFPageGetBoxRect(page, kCGPDFMediaBox).size;
UIGraphicsBeginImageContextWithOptions(size, YES, 1);
// flip the context
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, mediaBox.size.height);
CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1, -1);
// draw the page into the bitmap context
CGContextDrawPDFPage(UIGraphicsGetCurrentContext(), page);
CGPDFDocumentRelease(document);
// get the image from the context
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// save image as PNG file
[UIImagePNGRepresentation(image) writeToFile:somePath atomically:YES];