繁体   English   中英

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

[英]iOS Objective-C - Render JBIG2 image format

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

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

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

在JBIG2图像周围添加一个小小的PDF包装器只是为了能够将其渲染出来,这将浪费大量资源。 这个JBIG2解码器必须存在于iOS中的某个地方,那么如何使用它呢?

UPDATE

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

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

首先,你是正确的,本机iOS(和Mac OS)框架确实支持嵌入在PDF数据流中的JBIG2图像 - 实际上它是Core Graphics的一部分。

在iOS中读取图像的公共API是ImageIO 它通过添加通用图像文件读写功能扩展了Core Graphics。 它创建了CGImage对象,可以在CGContext使用它来解压缩和渲染。 可悲的是,它无法读取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支持的库:

分析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的私有实现。 这个库没有标题,所以它被认为是私有的,特别是在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];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM