[英]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支持的库:
这是实际的库:
> 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.