iOS Objective-C - 渲染 JBIG2 图像格式

标签 ios objective-c jbig2

自 PDF 规范 1.4 起,PDF 就支持 JBIG2 图像。因此所有 PDF 阅读器应用程序都可以读取 JBIG2 图像。我可以确认包含 JBIG2 图像的 PDF 在 iPhone 和 iPad 上正确呈现。

我想做的是渲染(或转换为 PNG)来自 Objective-C 的 JBIG2 图像,而不必将其放在 PDF 中。 JBIG2 图像以其自己的 JBIG2 原始格式(无任何类型的转换)存储在 PDF 文件中,就像普通图像对象一样,因此很明显在 iOS 中某处有一个 JBIG2 解码器库,否则这些无法解码。

那么,如果 JBIG2 图像不在 PDF 包装器中,我该如何在 iOS 上渲染该图像?它与该 PDF 图像对象中存在的数据完全相同,因此它将使用完全相同的解码器。

在 JBIG2 图像周围添加一个很小的 ​​PDF 包装器只是为了能够渲染它,这将是一种巨大的资源浪费。这个JBIG2解码器一定已经存在于iOS的某处,那么如何使用呢?

更新

如果 JBIG2 解码器在 iOS 中不可用,那么这意味着 PDF 阅读器正在使用他们自己的...在这种情况下,应该可以从开源 PDF 阅读器中删除解码器。

这是一个包含 JBIG2 和原始 JIBG2 的示例 PDF:http://www.filedropper.com/jbig2samples

最佳答案

首先,您是对的,原生 iOS(和 Mac OS)框架确实支持嵌入在 PDF 数据流中的 JBIG2 图像——实际上它是 Core Graphics 的一部分。

在 iOS 中读取图像的公共(public) API 是 ImageIO .它通过添加通用图像文件读写功能扩展了 Core Graphics。它创建可在 CGContext 中用于解压缩和渲染的 CGImage 对象。很遗憾,它无法读取 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 时在预览中显示 PDF 会显示实现 JBIG2 支持的库:

Instruments analyzing Preview.app

这是实际的库:

> 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 的私有(private)实现。这个库没有 header ,因此它被认为是私有(private)的,尤其是在 iOS 上。

关于如何使用 iOS 原生 JBIG2 解压缩,我们只剩下一个选择:您必须将 JBIG2 文件打包成最小的 PDF。我不认为运行时开销是相关的。

Addition 说明注释:从 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];

关于iOS Objective-C - 渲染 JBIG2 图像格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20946957/

相关文章:

ios - storyboard.instantiateInitialViewController 返回错误的 uiViewController

objective-c - 无法在 UINavigationBar 中重命名或设置新的 backBarButtonItem

pdf-generation - 由于其中的 JBIG2 图像,PDF 框生成空白图像

ios - 无法使用 ADT 编译 64 位 AIR ANE

ios - 缩放后的问题我想要完整图像,而不仅仅是缩放图像的一部分

android - MDM 可以限制用户更改日期时间设置吗

objective-c - missViewControllerAnimated 是否删除 Controller 的实例

ios - 使用 xmpp 或任何其他框架在 ios 中使用 google 帐户构建聊天应用程序

javascript - 使用 pdf.js 在浏览器中渲染 JBIG2 图像

Java - PDFBox - 带有 JBIG2 图像的 PDF