首页 数据库 mysql教程 Quartz 2D编程指南(14)

Quartz 2D编程指南(14)

Jun 07, 2016 pm 03:15 PM
pdf quartz 指南 文档 编程 解析

咳咳。。。。PDF文档解析 。。。网上找了好久没找到。。。。。自己翻译了。。水平不行。。。大家将就点随便看看了。这可是哥辛苦一下午翻译的

咳咳。。。。PDF文档解析 。。。网上找了好久没找到。。。。。自己翻译了。。水平不行。。。大家将就点随便看看了。这可是哥辛苦一下午翻译的啊。。累死我了。。


PDF文档解析

Quartz提供了让你检查PDF文档结构和内容流(contentstream)的函数.检查文档结构可以让你读取文档目录的条目和与每个条目相关的内容。通过递归地遍历目录,您可以检查整个文档。

一个PDF的内容流(contentstream)正如其名字所暗示的—一个连续的数据流 例如'BT 12 /F71 Tf (draw thistext) Tj . . . '此处PDF操作符以及他们的描述符都混有实际的PDF内容。检查内容流,你需要按顺序访问它。

本章揭示了如何查看PDF文档的结构和解析一个PDF文件的内容。

 

检查PDF文档结构

PDF文件可能包含多个页面的图像和文本。您可以使用Quartz访问文档和页面级别的元数据以及PDF页上的对象。本节提供了一个非常简短的介绍,关于您可以访问的元数据。

 

一个PDF文档对象 (CGPDFDocument)包含了所有的信息,涉及到一个PDF文档,包括它的目录和内容。目录中的条目的递归地描述了PDF文档的内容。你可以访问一个PDF文档的内容通过调用函数CGPDFDocumentGetCatalog

 

一个PDF页面对象(CGPDFPage)代表PDF文档中的一页且包含此特定的页面所有信息,包括页面字典和页面内容。您可以获得一个页面字典通过调用该函数CGPDFPageGetDictionary

 

图 14-1 展示了描述了两张图片的元数据—组成了图13-2的PDF文件。

 Quartz 2D编程指南(14)

你可以通过访问PDF的元数据获得更多有用的信息。图14-1只是一个示例。例如,您可以通过使用图14-1中的代码检查一个PDF是否有缩略图(见图14-2)。

 

清单  14-1  得到PDF的缩略视图

CGPDFDictionaryRef d;
登录后复制
CGPDFStreamRef stream; // represents a sequence of bytes
登录后复制
d = CGPDFPageGetDictionary(page);
登录后复制
// check for thumbnail data
登录后复制
if (CGPDFDictionaryGetStream (d, “Thumb”, &stream)){
登录后复制
    // get the data if it exists
登录后复制
    data = CGPDFStreamCopyData (stream, &format);
登录后复制

Quartz为你执行了所有数据流的解密和解密工作。

 

图 14-2  缩略图片

Quartz 2D编程指南(14) 

Quartz提供了很多的功能,您可以使用它来获得PDF的元数据中对应项的指定值。例如,您使用函数CGPDFObjectGetValue传入一个CGPDFObjectRef,和一个PDF对象类型(kCGPDFObjectTypeBooleankCGPDFObjectTypeInteger, 等等),以及一个存储值的存储空间。返回时,此存储空间就被得到的值填充了。

 

还有很多其他的函数可以用来遍历PDF文件的层次结构来访问各个节点和他们的子节点。例如,CGPDFArray函数(CGPDFArrayGetBooleanCGPDFArrayGet DictionaryCGPDFArrayGetInteger,等等)  允许您访问数组的值,以检索特定类型的值。你可以通过阅读阅读PDF规范来找到更多关于如何使用这些函数。

 

解析PDF内容

 

你使用CGPDFScanner对象(CGPDFScannerRef数据类型)来解析一个PDF内容流。CGPDFScanner对象调用在流中注册了回调方法的任何操作符的回调方法。

 

你可以执行以下部分所描述的任务来解析内容流:

1.“为操作符写回调方法”你需要为你要操作的操作符编写回调方法。

2.“创建和设置操作表”。

3.“打开PDF文档”。

4.“扫描每页的内容流”。

当这么做的时候,你应该确保释放了 the scanner, content stream,and operator table。

 

下面的部分展示如何解析内容流找到标记-内容操作符marked-content operators)(见表14-1)。标记的内容操作符只代表部分用于PDF内容的PDF操作符。当您编写自己的代码时,你最好寻找适合您的应用程序的PDF操作符。

 

表 14-1 标注的内容操作符代表一些你可以解析的PDF操作符

Operator

Description

MP

DP

BMC

标志着一个标记内容序列的开始(开始标记内容)和标志一个内容序列结尾的EMC

BDC

标志着一个标记内容序列的开始和标志一个内容序列结尾的EMC

EMC

标志着一个以BMCBDC

 

为操作符编写回调方法

当Quartz调用你的PDF操作符的回调方法时,它通过你的回调方法传递了一个CGPDFScanner对象和一个指向任何必要信息的指针。通常,你的回调方法检索任何与操作符相关联的项。例如,在14-2所展示的清单中对应于MP操作符的回调方法调用了CGPDFScannerPopName函数从堆栈中检索与操作符相关联的字符串。如果清单中的代码成功的从scanner栈中检索出name,就打印出来。

Quartz有各式各样的CGPDFScannerPop函数用于检索objects,Boolean values, names, numbers, strings, arrays, dictionaries, and streams.每个函数都返回一个布尔值表明是否成功检索了该项。

 

清单14-2 MP操作符的回调方法

static void
登录后复制
op_MP (CGPDFScannerRef s, void *info)
登录后复制
{
登录后复制
    const char *name;
登录后复制
 
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
    if (!CGPDFScannerPopName(s, &name))
登录后复制
        return;
登录后复制
 
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
    printf("MP /%s\n", name);
登录后复制
}
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制


创建并设置操作表 

一个CGPDFOperatorTable对象存储了你编写的PDF操作符回调函数。函数CGPDFOperatorTableCreate创建了一个操作符表,如清单14-3所示。当你创建了一个操作符表之后,你要为每个你要加入到表中的回调方法调用函数 CGPDFOperatorTableSetCallback你传入了操作表,指定PDF操作符的字符串,以及一个你编写用来处理指定操作符的回调函数的指针。你可以随意命名这些回调函数。只要确保回调函数的名字和你传入CGPDFOperatorTableSetCallback函数的名字是相同的即可。

 

代码清单14-3为表14-1中列出的每个标记-文本操作符 设置了一个回调方法。你的应用应该为你感兴趣的那些操作符设置回调方法。PDF操作符字符串由Adobe PDF Reference 制定。


清单 14-3 为操作表设置回调方法

CGPDFOperatorTableRef myTable;
登录后复制
 
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
myTable = CGPDFOperatorTableCreate();
登录后复制
 
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
CGPDFOperatorTableSetCallback (myTable, "MP", &op_MP);
登录后复制
CGPDFOperatorTableSetCallback (myTable, "DP", &op_DP);
登录后复制
CGPDFOperatorTableSetCallback (myTable, "BMC", &op_BMC);
登录后复制
CGPDFOperatorTableSetCallback (myTable, "BDC", &op_BDC);
登录后复制
CGPDFOperatorTableSetCallback (myTable, "EMC", &op_EMC);
登录后复制



打开PDF文档
 

在你扫描PDF文档之前,你必须打开它。清单14-4 展示了 从代码中提供的URL创建一个CGPDFDocument对象的代码片段。注意此清单只是一个代码段,所以不是所有变量都定义了。此清单中用数字标注的代码行都有详细的解释。

 

清单 14-4 从一个URL打开一个PDF文档


CGPDFDocumentRef myDocument;
登录后复制
myDocument = CGPDFDocumentCreateWithURL(url);<span>// 1</span>
登录后复制
if (myDocument == NULL) {<span>// 2</span>
登录后复制
        error ("can't open `%s'.", filename);
登录后复制
        CFRelease (url);
登录后复制
        return EXIT_FAILURE;
登录后复制
登录后复制
登录后复制
}
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
CFRelease (url);
登录后复制
if (CGPDFDocumentIsEncrypted (myDocument)) {<span>// 3</span>
登录后复制
    if (!CGPDFDocumentUnlockWithPassword (myDocument, "")) {
登录后复制
        printf ("Enter password: ");
登录后复制
        fflush (stdout);
登录后复制
        password = fgets(buffer, sizeof(buffer), stdin);
登录后复制
        if (password != NULL) {
登录后复制
            buffer[strlen(buffer) - 1] = '\0';
登录后复制
            if (!CGPDFDocumentUnlockWithPassword (myDocument, password))
登录后复制
                error("invalid password.");
登录后复制
        }
登录后复制
    }
登录后复制
登录后复制
}
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
if (!CGPDFDocumentIsUnlocked (myDocument)) {<span>// 4</span>
登录后复制
        error("can't unlock `%s'.", filename);
登录后复制
        CGPDFDocumentRelease(myDocument);
登录后复制
        return EXIT_FAILURE;
登录后复制
登录后复制
登录后复制
    }
登录后复制
登录后复制
}
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
 if (CGPDFDocumentGetNumberOfPages(document) == 0) {<span>// 5</span>
登录后复制
        CGPDFDocumentRelease(document);
登录后复制
        return EXIT_FAILURE;
登录后复制
登录后复制
登录后复制
}
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

此处代码做了哪些: 

1. 利用代码中提供的URL创建一个CGPDFDocument对象。

2. 检查以确保CGPDFDocument对象被创建。如果没有,代码退出,因为没有document继续执行没有意义。

3. 检查document是否加密。如果document加密,则代码试图利用空密码打开文档。如果失败,代码要求用户提供密码并试图用此密码解锁文档。

4. 检查document是否解锁,如果没有,代码退出。

5. 检查以确保document至少有一页,否则,代码退出。

 

 

扫描每页的内容流

清单14-5 代码段扫描文档每一页。当此scanner遇到一个注册了回调方法的PDF操作符,Quartz就调用此回调方法。此清单中用数字标注的代码行都有详细的解释。

清单 14-5  扫描文档的每一页

int k;
登录后复制
CGPDFPageRef myPage;
登录后复制
CGPDFScannerRef myScanner;
登录后复制
CGPDFContentStreamRef myContentStream;
登录后复制
 
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
numOfPages = CGPDFDocumentGetNumberOfPages (myDocument);<span>// 1</span>
登录后复制
for (k = 0; k 
登录后复制
    myPage = CGPDFDocumentGetPage (myDocument, k + 1 );<span>// 2</span>
登录后复制
    myContentStream = CGPDFContentStreamCreateWithPage (myPage);<span>// 3</span>
登录后复制
    myScanner = CGPDFScannerCreate (myContentStream, myTable, NULL);<span>// 4</span>
登录后复制
    CGPDFScannerScan (myScanner);<span>// 5</span>
登录后复制
    CGPDFPageRelease (myPage);<span>// 6</span>
登录后复制
    CGPDFScannerRelease (myScanner);<span>// 7</span>
登录后复制
    CGPDFContentStreamRelease (myContentStream);<span>// 8</span>
登录后复制
 }
登录后复制
 CGPDFOperatorTableRelease(myTable);
登录后复制

此处代码解释: 

1. 得到你先前打开的document的页数。见“Open thePDF Document.”

2. 检索扫描一页。页数以一开始。

3. 为此页创建内容流。

4. 为内容流创建一个scanner。你必须传入先前创建且在回调方法中设置的内容流和操作表。见“Create andSet Up the Operator Table.” 你也可以传入你的回调方法中需要的任何数据。

5. 解析与scanner相关联的内容流。当Quartz每次遇到你在回调方法中提供的操作符时就会调用相应回调方法。

6. 释放 page

7. 释放 scanner

8. 释放 content stream

9. 释放 operator table 在PDF扫描完所有页之后。

 

原帖地址:http://blog.csdn.net/xiao_se7en/article/details/7620056
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

使用正则表达式去除 PHP 数组中的重复值 使用正则表达式去除 PHP 数组中的重复值 Apr 26, 2024 pm 04:33 PM

使用正则表达式从PHP数组中去除重复值的方法:使用正则表达式/(.*)(.+)/i匹配并替换重复项。遍历数组元素,使用preg_match检查匹配情况。如果匹配,跳过值;否则,将其添加到无重复值的新数组中。

编程是干啥的,学了有什么用 编程是干啥的,学了有什么用 Apr 28, 2024 pm 01:34 PM

1、编程可以用于开发各种软件和应用程序,包括网站、手机应用、游戏和数据分析工具等。它的应用领域非常广泛,覆盖了几乎所有行业,包括科学研究、医疗保健、金融、教育、娱乐等。2、学习编程可以帮助我们提高问题解决能力和逻辑思维能力。编程过程中,我们需要分析和理解问题,找出解决方案,并将其转化为代码。这种思维方式能够培养我们的分析和抽象能力,提高我们解决实际问题的能力。

编码的关键:为初学者释放 Python 的力量 编码的关键:为初学者释放 Python 的力量 Oct 11, 2024 pm 12:17 PM

Python通过其易学性和强大功能,是初学者的理想编程入门语言。其基础包括:变量:用于存储数据(数字、字符串、列表等)。数据类型:定义变量中数据的类型(整数、浮点数等)。运算符:用于数学运算和比较。控制流:控制代码执行流(条件语句、循环)。

pdf怎么转换为word pdf怎么转换为word Apr 30, 2024 pm 05:58 PM

1、使用在线转换工具,如Smallpdf、Adobe Acrobat或Zamzar。2、这些工具通常提供简单易用的界面,允许用户上传 PDF 文件并选择将其转换为 Word 格式。3、转换完成后,用户可以下载 Word 文档并进行进一步编辑。4、使用专业的PDF转换软件,如Adobe Acrobat Pro或Wondershare PDFelement。

Java 变得简单:编程能力的初学者指南 Java 变得简单:编程能力的初学者指南 Oct 11, 2024 pm 06:30 PM

JavaMadeSimple:ABeginner'sGuidetoProgrammingPower简介Java是一种强大的编程语言,广泛应用于从移动应用程序到企业级系统的各种领域。对于初学者来说,Java的语法简洁易懂,是学习编程的理想选择。基本语法Java使用基于类的面向对象编程范式。类是将相关数据和行为组织在一起的模板。以下是一个简单的Java类示例:publicclassPerson{privateStringname;privateintage;

创造未来:面向零基础的 Java 编程 创造未来:面向零基础的 Java 编程 Oct 13, 2024 pm 01:32 PM

Java是热门编程语言,适合初学者和经验丰富的开发者学习。本教程从基础概念出发,逐步深入讲解高级主题。安装Java开发工具包后,可通过创建简单的“Hello,World!”程序实践编程。理解代码后,使用命令提示符编译并运行程序,控制台上将输出“Hello,World!”。学习Java开启了编程之旅,随着掌握程度加深,可创建更复杂的应用程序。

使用 Python 解决问题:作为初学者,解锁强大的解决方案 使用 Python 解决问题:作为初学者,解锁强大的解决方案 Oct 11, 2024 pm 08:58 PM

Python 使初学者能够解决问题。其用户友好的语法、广泛的库以及变量、条件语句和循环等功能可实现高效的代码开发。从管理数据到控制程序流程和执行重复任务,Python 提供了

揭秘 C:为新程序员提供一条清晰简单的道路 揭秘 C:为新程序员提供一条清晰简单的道路 Oct 11, 2024 pm 10:47 PM

C是一种初学者学习系统编程的理想选择,它包含以下组件:头文件、函数和主函数。一个简单的C程序可以打印“HelloWorld”,需要包含标准输入/输出函数声明的头文件,并在主函数中使用printf函数来打印。通过使用GCC编译器可以编译和运行C程序。掌握基础后,可以继续学习数据类型、函数、数组和文件处理等主题,以成为熟练的C程序员。

See all articles