SlideShare a Scribd company logo
1 of 41
iOS での PDF 処理あれこれ

       越智 修司

     @ponpoko1968
自己紹介
越智修司

•       KLab( くらぶ ) 株式会社

•       ソシャゲの会社でソシャゲじゃ無いもの作ってます

•       アプリ・サービスのプロトタイピング

•       有名アーティスト・アイドルのファンクラブアプリ開発

•       最近はデータ解析

    •     python,R など
動機
•   自炊始めた
•   PDF リーダーをいろいろ試してみた
•   要望
    •       読書内容を残したい・シェア
        •    evernote
        •    facebook


    •       視力が落ちてきた人 ( つまり自分 ) も
            読みやすく
クリップリーダー
•   PDF リーダー
苦労したこと
•   メモリ消費
•   目次の抽出
•   文字列の抽出
PDF 描画 (1)
•   CGContextDrawPDFPage() を使えば OK
•   ビットマップコンテクストに描画して永
    続化すればキャッシュできる
PDF 描画 (2)
CGPDFDocumentRef pdfDocument
    = CGPDFDocumentCreateWithURL(url);

// ページ番号からページを取得
CGPDFPageRef page
    = CGPDFDocumentGetPage ( pdfDocument, pageNum );
CGContextDrawPDFPage( context, page );
CGPDFDocumentRelease( pdfDocument );
PDF 描画 (3)

•       注意点
    •       メモリを消費します。
    •       しかもページを取得して描画するたびに消費量
            が増えます。
    •       対策
        •    ページレンダリングの都度 CGPDFDocument を開放して
             開き直す。→パフォーマンス劣化
        •    didReceiveMemoryWarning を受け取ったらいったん閉じ
             て再開。
「目次」機能
Core Graphics での PDF の構造
•    階層化されたオブジェクトの集合体
    • ページ
    • フォント
    • コンテントストリーム
Document management — Portable
document format — Part 1: PDF 1.7 より
PDF 描画 (2)
CGPDFDocumentRef pdfDocument
    = CGPDFDocumentCreateWithURL(url);

// ページ番号からページを取得
CGPDFPageRef page
    = CGPDFDocumentGetPage ( pdfDocument, pageNum );
CGContextDrawPDFPage( context, page );
CGPDFDocumentRelease( pdfDocument );
Core Graphics での PDF の構造
•   Document Catalog という辞書から文書構
    造を取り出す

•   オブジェクト単位の情報は
    CGPDFDictionary として扱われる

• 配列は CGPDFArray として扱われる場合と
  、 'First','Next' キーから参照できるリンク
  リストになっている場合がある( Lisp の
  car と cdr のようなもの )
• しかも Composite 構造になっている
リンクリスト



        Next



First
Pages
ページ 並びの取得
CGPDFDictionaryRef catalog=CGPDFDocumentGetCatalog( document_ );
CGPDFDictionaryRef pages =NULL;
CGPDFDictionaryGetDictionary(catalog, "Pages", &pages);

// 先頭の要素を取得
CGPDFArrayRef pagesArray= NULL;
CGPDFDictionaryGetDictionary(pages, "Kids", &pagesArray);

int cnt = CGPDFArrayGetCount (pagesArray );
for ( int i = 0; i < cnt; i++ ){
   const char *typeString;
   CGPDFDictionaryRef pageDict;
   CGPDFArrayGetDictionary(pagesArray, i, &pageDict );
   CGPDFDictionaryGetName(pageDict, "Type", &typeString );
   if(strncmp("Page",typeString,strlen("Page"))==0 ){
        // pageDict オブジェクトへのポインタと、ページ番号を NSDictionary
   に保存
   [pageNumDict setValue:[NSNumber numberWithInt:pageNum]
               forKey:[NSString stringWithFormat:@"%p",pageDict] ];

  }
目次構造の取得




Document management — Portable document
format — Part 1: PDF 1.7 より
PDF 文書構造(1)
CGPDFDictionaryRef catalog=CGPDFDocumentGetCatalog( document_ );
CGPDFDictionaryRef outlines=NULL;
CGPDFDictionaryGetDictionary(catalog, "Outlines", &outlines );

// 先頭の要素を取得
CGPDFDictionaryRef first = NULL;
CGPDFDictionaryGetDictionary(outlines, "First", &first );

// 見出しを取得
CGPDFStringRef title;
CGPDFDictionaryGetString ( first, "Title", &title );

// 次の章 (cdr 部 ) を取得
CGPDFDictionaryRef next = NULL;
CGPDFDictionaryGetDictionary(outlines, "Next", &next);

// 小見出し( car 部)を取得
CGPDFDictionaryRef children;
CGPDFDictionaryGetString ( first, "First", &children);
PDF 文書構造(2)
// ページオブジェクトを取得
CGPDFDictionaryRef page;
CGPDFDictionaryDictionary ( first, "D", &title );

// 「 D 」キーがなく、ページオブジェクトを直接参照できない場合
CGPDFStringRef dest;
CGPDFDictionaryGetString(dict, "Dest", &dest );
Document management — Portable
document format — Part 1: PDF 1.7 より
ページ番号と文書構造のリンク

val       key

 0

  1

 2

 3

      ・
      ・
      ・

  n             Pages   Contents
文字列抽出機能




•   コンテントストリームのなかから、文字
    列描画命令部分を取り出す
コンテントストリーム




ページ上で表現される一連の描画命令とデータ
PDF のオペレータ

param1 param2 param3 param4 op


•   後置記法
•   パラメータは LIFO スタックに積まれる

           param4

           param3

           param2

           param1
PDF の文字列描画
BT                             % Begin Text
/F1 24 Tf                      % フォント指定
                               % /F1 がフォントを表現するシンボ
   ル
1 0 0 1 72 648 Tm              % 描画位置の指定

(Hello World) Tj               % 文字列描画 -- (と )が引用符
1 0 0 1 72 612 Tm
                                 % non-ASCII 文字列
<4D53835383568362834E3234837C834383938367> Tj
1 0 0 1 72 576 Tm
0.5 g                            % グレイスケール
<82BB82EA82F08A44904682C982B582BD82E082CC> Tj
ET                               % End Text




                                      「 PDF by Hand 」
                                      http://www.kobu.com/doc s/pdf/pdfxhand.htm
                                      より
文字列描画オペレータ




•   Tj オペレータ
文字列抽出
// コールバック関数を設定する
CGPDFOperatorTableRef table_;
CGPDFOperatorTableSetCallback(table_,   "BT",stringBlockBeginsCallback);
CGPDFOperatorTableSetCallback(table_,   "ET", stringBlockEndedCallback);
CGPDFOperatorTableSetCallback(table_,   "TJ", stringArrayCallback);
CGPDFOperatorTableSetCallback(table_,   "Tj", stringCallback);
CGPDFOperatorTableSetCallback(table_,   "Tf", fontCallback);

// ページに適用
CGPDFContentStreamRef contentStream =
   CGPDFContentStreamCreateWithPage(page);
CGPDFScannerRef scanner = CGPDFScannerCreate(contentStream, table_,
   self); // userinfo として self を指定
bool ret = CGPDFScannerScan(scanner);
文字列抽出コールバック
static void stringCallback(CGPDFScannerRef inScanner, void *userInfo)
{
  PDFStringExtractor *zelf = (PDFStringExtractor *)userInfo;
  CGPDFStringRef string=NULL;

 if(CGPDFScannerPopString(inScanner, &string)) {

    // ↑LIFO なのでポップする
    // 座標関連の命令を取り出すときは注意

   NSString* s   =   [zelf stringWithPDFString:string];
文字列抽出コールバック
static void stringCallback(CGPDFScannerRef inScanner, void *userInfo)
{
  PDFStringExtractor *zelf = (PDFStringExtractor *)userInfo;
  CGPDFStringRef string=NULL;

 if(CGPDFScannerPopString(inScanner, &string)) {


      // ↑ 全然文字列じゃない!!!
   NSString* s   =   [zelf stringWithPDFString:string];
レンダラの気持ちになって考える
CID


•   PDF における " 文字列 " は、実際には CID の列で
    あることがある

•   CID= グリフ ( 字形 ) を一意に識別するための ID

•   CID と文字コードのマッピングは文字列描画に用
    いるフォントによって異なる
フォント指定が重要
BT                             % Begin Text
/F1 24 Tf                      % フォント指定
                               % /F1 がフォントを表現するシンボ
   ル
1 0 0 1 72 648 Tm              % 描画位置の指定

(Hello World) Tj               % 文字列描画 -- (と )が引用符
1 0 0 1 72 612 Tm
                                 % non-ASCII 文字列
<4D53835383568362834E3234837C834383938367> Tj
1 0 0 1 72 576 Tm
0.5 g                            % グレイスケール
<82BB82EA82F08A44904682C982B582BD82E082CC> Tj
ET                               % End Text




                                      「 PDF by Hand 」
                                      http://www.kobu.com/doc s/pdf/pdfxhand.htm
                                      より
CGPDFDictionaryRef pageDict = CGPDFPageGetDictionary(page);
CGPDFDictionaryRef resourceDict = NULL;
CGPDFDictionaryRef fontDict = NULL;
// フォント辞書をスキャン
if(CGPDFDictionaryGetDictionary(pageDict, "Resources", &resourceDict )
   ) {
  if(CGPDFDictionaryGetDictionary(resourceDict, "Font", &fontDict ) )
   {

      CGPDFDictionaryApplyFunction(fontDict,enumerateFontsInDictionary,se
      lf);
     }
    }

static void enumerateFontsInDictionary(const char *key, CGPDFObjectRef
   value, void *info) {
   // フォント情報をキャッシュする

}
フォントのエンコーディング情報
•   Encoding
    •   "Identity-H","Identity-V"
        •   DescendantFont
            •   /Registry (Adobe)
            •   /Ordering (Japan-1)
            •   /Supplement (6)
    •   CMAP 名
CID ファイル :EUC-H の例


100 begincidrange    ← 100 個の区間があることを示す
<20> <7e>      231   ← cid231 〜 313 は printable ASCII の区間
<8ea0> <8edf> 326
<a1a1> <a1fe> 633
<a2a1> <a2ae> 727
<a2ba> <a2c1> 741
   .
   .
   .
endcidrange
課題




•   対応できてないパターンがある
•   テキスト領域認識
•   全文検索
参考文献
•   Life is Beautiful ( 中島聡氏 )
    •   CloudReaders の開発
    •   PDF レンダリングのメモリ消費の問題
        を指摘
    •   超巨大ページにも対応
•   木下誠氏のマイコミジャーナルの記事
    •   Core Text を用いた CID→Unicode の簡便
        な解決案が提示されています
    •   http://news.mynavi.jp/column/iphone/03
        9/index.html
参考文献 (2)
     •   通称フグ本

     •   CID などアドビ社の多国
         語対応の情報

     •   鈍器としても使えます
参考文献 (3)
     •   もっと早く出ていれ
         ば。。。
PDF Voyeur




https://github.com/below/PDF-Voyeur.git

More Related Content

Viewers also liked

Core Animation 使って見た
Core Animation 使って見たCore Animation 使って見た
Core Animation 使って見たOCHI Shuji
 
スペースハルク
スペースハルクスペースハルク
スペースハルクOCHI Shuji
 
第3回関西ソーシャルゲーム勉強会 アクセス時間帯の分析
第3回関西ソーシャルゲーム勉強会 アクセス時間帯の分析第3回関西ソーシャルゲーム勉強会 アクセス時間帯の分析
第3回関西ソーシャルゲーム勉強会 アクセス時間帯の分析OCHI Shuji
 
第4回関西ソーシャルゲーム勉強会 ソーシャルゲームのビジネスインテリジェンス
第4回関西ソーシャルゲーム勉強会 ソーシャルゲームのビジネスインテリジェンス第4回関西ソーシャルゲーム勉強会 ソーシャルゲームのビジネスインテリジェンス
第4回関西ソーシャルゲーム勉強会 ソーシャルゲームのビジネスインテリジェンスOCHI Shuji
 
デブサミ関西2013 「ソーシャルゲームのデータサイエンス」
デブサミ関西2013 「ソーシャルゲームのデータサイエンス」デブサミ関西2013 「ソーシャルゲームのデータサイエンス」
デブサミ関西2013 「ソーシャルゲームのデータサイエンス」OCHI Shuji
 
2012 05-19第44回cocoa勉強会発表資料
2012 05-19第44回cocoa勉強会発表資料2012 05-19第44回cocoa勉強会発表資料
2012 05-19第44回cocoa勉強会発表資料OCHI Shuji
 
第1回関西ソーシャルゲーム勉強会 kpi発表
第1回関西ソーシャルゲーム勉強会 kpi発表第1回関西ソーシャルゲーム勉強会 kpi発表
第1回関西ソーシャルゲーム勉強会 kpi発表OCHI Shuji
 
ソーシャルゲームのデータ分析基盤としてのAWS Jaws ug三都物語LT
ソーシャルゲームのデータ分析基盤としてのAWS Jaws ug三都物語LTソーシャルゲームのデータ分析基盤としてのAWS Jaws ug三都物語LT
ソーシャルゲームのデータ分析基盤としてのAWS Jaws ug三都物語LTOCHI Shuji
 

Viewers also liked (9)

Core Animation 使って見た
Core Animation 使って見たCore Animation 使って見た
Core Animation 使って見た
 
スペースハルク
スペースハルクスペースハルク
スペースハルク
 
Manual en
Manual enManual en
Manual en
 
第3回関西ソーシャルゲーム勉強会 アクセス時間帯の分析
第3回関西ソーシャルゲーム勉強会 アクセス時間帯の分析第3回関西ソーシャルゲーム勉強会 アクセス時間帯の分析
第3回関西ソーシャルゲーム勉強会 アクセス時間帯の分析
 
第4回関西ソーシャルゲーム勉強会 ソーシャルゲームのビジネスインテリジェンス
第4回関西ソーシャルゲーム勉強会 ソーシャルゲームのビジネスインテリジェンス第4回関西ソーシャルゲーム勉強会 ソーシャルゲームのビジネスインテリジェンス
第4回関西ソーシャルゲーム勉強会 ソーシャルゲームのビジネスインテリジェンス
 
デブサミ関西2013 「ソーシャルゲームのデータサイエンス」
デブサミ関西2013 「ソーシャルゲームのデータサイエンス」デブサミ関西2013 「ソーシャルゲームのデータサイエンス」
デブサミ関西2013 「ソーシャルゲームのデータサイエンス」
 
2012 05-19第44回cocoa勉強会発表資料
2012 05-19第44回cocoa勉強会発表資料2012 05-19第44回cocoa勉強会発表資料
2012 05-19第44回cocoa勉強会発表資料
 
第1回関西ソーシャルゲーム勉強会 kpi発表
第1回関西ソーシャルゲーム勉強会 kpi発表第1回関西ソーシャルゲーム勉強会 kpi発表
第1回関西ソーシャルゲーム勉強会 kpi発表
 
ソーシャルゲームのデータ分析基盤としてのAWS Jaws ug三都物語LT
ソーシャルゲームのデータ分析基盤としてのAWS Jaws ug三都物語LTソーシャルゲームのデータ分析基盤としてのAWS Jaws ug三都物語LT
ソーシャルゲームのデータ分析基盤としてのAWS Jaws ug三都物語LT
 

Similar to Cocoa勉強会pdf関連

卒研発表
卒研発表卒研発表
卒研発表yayugu
 
コミケの取りまとめをしたので
コミケの取りまとめをしたのでコミケの取りまとめをしたので
コミケの取りまとめをしたのでKenichiro MATOHARA
 
【関東GPGPU勉強会#4】GTX 1080でComputer Vision アルゴリズムを色々動かしてみる
【関東GPGPU勉強会#4】GTX 1080でComputer Visionアルゴリズムを色々動かしてみる【関東GPGPU勉強会#4】GTX 1080でComputer Visionアルゴリズムを色々動かしてみる
【関東GPGPU勉強会#4】GTX 1080でComputer Vision アルゴリズムを色々動かしてみるYasuhiro Yoshimura
 
Core Graphicsでつくる自作UIコンポーネント入門
Core Graphicsでつくる自作UIコンポーネント入門Core Graphicsでつくる自作UIコンポーネント入門
Core Graphicsでつくる自作UIコンポーネント入門cocopon
 
2008.10.18 L4u Tech Talk
2008.10.18 L4u Tech Talk2008.10.18 L4u Tech Talk
2008.10.18 L4u Tech Talkmitamex4u
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由kikairoya
 
20141017 introduce razor
20141017 introduce razor20141017 introduce razor
20141017 introduce razordo_aki
 
Programming camp 2008, Codereading
Programming camp 2008, CodereadingProgramming camp 2008, Codereading
Programming camp 2008, CodereadingHiro Yoshioka
 
TreeFrog Frameworkの紹介
TreeFrog Frameworkの紹介TreeFrog Frameworkの紹介
TreeFrog Frameworkの紹介ao27
 
Tide - SmalltalkでSPA
Tide - SmalltalkでSPATide - SmalltalkでSPA
Tide - SmalltalkでSPAMasashi Umezawa
 
C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1信之 岩永
 
Inside of excel 方眼紙撲滅委員会 #pyfes
Inside of excel 方眼紙撲滅委員会 #pyfesInside of excel 方眼紙撲滅委員会 #pyfes
Inside of excel 方眼紙撲滅委員会 #pyfesTakeshi Komiya
 
条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化Takuya Ueda
 
(ゲームじゃない方の)switchで遊びたい話
(ゲームじゃない方の)switchで遊びたい話(ゲームじゃない方の)switchで遊びたい話
(ゲームじゃない方の)switchで遊びたい話Masanori Masui
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#信之 岩永
 
Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理土岐 孝平
 

Similar to Cocoa勉強会pdf関連 (20)

卒研発表
卒研発表卒研発表
卒研発表
 
コミケの取りまとめをしたので
コミケの取りまとめをしたのでコミケの取りまとめをしたので
コミケの取りまとめをしたので
 
【関東GPGPU勉強会#4】GTX 1080でComputer Vision アルゴリズムを色々動かしてみる
【関東GPGPU勉強会#4】GTX 1080でComputer Visionアルゴリズムを色々動かしてみる【関東GPGPU勉強会#4】GTX 1080でComputer Visionアルゴリズムを色々動かしてみる
【関東GPGPU勉強会#4】GTX 1080でComputer Vision アルゴリズムを色々動かしてみる
 
Core Graphicsでつくる自作UIコンポーネント入門
Core Graphicsでつくる自作UIコンポーネント入門Core Graphicsでつくる自作UIコンポーネント入門
Core Graphicsでつくる自作UIコンポーネント入門
 
2008.10.18 L4u Tech Talk
2008.10.18 L4u Tech Talk2008.10.18 L4u Tech Talk
2008.10.18 L4u Tech Talk
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
 
計算機理論入門09
計算機理論入門09計算機理論入門09
計算機理論入門09
 
20141017 introduce razor
20141017 introduce razor20141017 introduce razor
20141017 introduce razor
 
Programming camp 2008, Codereading
Programming camp 2008, CodereadingProgramming camp 2008, Codereading
Programming camp 2008, Codereading
 
TreeFrog Frameworkの紹介
TreeFrog Frameworkの紹介TreeFrog Frameworkの紹介
TreeFrog Frameworkの紹介
 
仮想記憶の構築法
仮想記憶の構築法仮想記憶の構築法
仮想記憶の構築法
 
Tide - SmalltalkでSPA
Tide - SmalltalkでSPATide - SmalltalkでSPA
Tide - SmalltalkでSPA
 
Cocoa勉強会201208
Cocoa勉強会201208Cocoa勉強会201208
Cocoa勉強会201208
 
C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1
 
Inside of excel 方眼紙撲滅委員会 #pyfes
Inside of excel 方眼紙撲滅委員会 #pyfesInside of excel 方眼紙撲滅委員会 #pyfes
Inside of excel 方眼紙撲滅委員会 #pyfes
 
条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化
 
(ゲームじゃない方の)switchで遊びたい話
(ゲームじゃない方の)switchで遊びたい話(ゲームじゃない方の)switchで遊びたい話
(ゲームじゃない方の)switchで遊びたい話
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
 
HTML5
HTML5HTML5
HTML5
 
Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理
 

Recently uploaded

【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 

Recently uploaded (14)

【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 

Cocoa勉強会pdf関連

  • 1. iOS での PDF 処理あれこれ 越智 修司 @ponpoko1968
  • 2. 自己紹介 越智修司 • KLab( くらぶ ) 株式会社 • ソシャゲの会社でソシャゲじゃ無いもの作ってます • アプリ・サービスのプロトタイピング • 有名アーティスト・アイドルのファンクラブアプリ開発 • 最近はデータ解析 • python,R など
  • 3. 動機 • 自炊始めた • PDF リーダーをいろいろ試してみた • 要望 • 読書内容を残したい・シェア • evernote • facebook • 視力が落ちてきた人 ( つまり自分 ) も 読みやすく
  • 4. クリップリーダー • PDF リーダー
  • 5. 苦労したこと • メモリ消費 • 目次の抽出 • 文字列の抽出
  • 6. PDF 描画 (1) • CGContextDrawPDFPage() を使えば OK • ビットマップコンテクストに描画して永 続化すればキャッシュできる
  • 7. PDF 描画 (2) CGPDFDocumentRef pdfDocument = CGPDFDocumentCreateWithURL(url); // ページ番号からページを取得 CGPDFPageRef page = CGPDFDocumentGetPage ( pdfDocument, pageNum ); CGContextDrawPDFPage( context, page ); CGPDFDocumentRelease( pdfDocument );
  • 8. PDF 描画 (3) • 注意点 • メモリを消費します。 • しかもページを取得して描画するたびに消費量 が増えます。 • 対策 • ページレンダリングの都度 CGPDFDocument を開放して 開き直す。→パフォーマンス劣化 • didReceiveMemoryWarning を受け取ったらいったん閉じ て再開。
  • 10. Core Graphics での PDF の構造 • 階層化されたオブジェクトの集合体 • ページ • フォント • コンテントストリーム
  • 11. Document management — Portable document format — Part 1: PDF 1.7 より
  • 12. PDF 描画 (2) CGPDFDocumentRef pdfDocument = CGPDFDocumentCreateWithURL(url); // ページ番号からページを取得 CGPDFPageRef page = CGPDFDocumentGetPage ( pdfDocument, pageNum ); CGContextDrawPDFPage( context, page ); CGPDFDocumentRelease( pdfDocument );
  • 13. Core Graphics での PDF の構造 • Document Catalog という辞書から文書構 造を取り出す • オブジェクト単位の情報は CGPDFDictionary として扱われる • 配列は CGPDFArray として扱われる場合と 、 'First','Next' キーから参照できるリンク リストになっている場合がある( Lisp の car と cdr のようなもの ) • しかも Composite 構造になっている
  • 14. リンクリスト Next First
  • 15. Pages
  • 16. ページ 並びの取得 CGPDFDictionaryRef catalog=CGPDFDocumentGetCatalog( document_ ); CGPDFDictionaryRef pages =NULL; CGPDFDictionaryGetDictionary(catalog, "Pages", &pages); // 先頭の要素を取得 CGPDFArrayRef pagesArray= NULL; CGPDFDictionaryGetDictionary(pages, "Kids", &pagesArray); int cnt = CGPDFArrayGetCount (pagesArray ); for ( int i = 0; i < cnt; i++ ){ const char *typeString; CGPDFDictionaryRef pageDict; CGPDFArrayGetDictionary(pagesArray, i, &pageDict ); CGPDFDictionaryGetName(pageDict, "Type", &typeString ); if(strncmp("Page",typeString,strlen("Page"))==0 ){ // pageDict オブジェクトへのポインタと、ページ番号を NSDictionary に保存 [pageNumDict setValue:[NSNumber numberWithInt:pageNum] forKey:[NSString stringWithFormat:@"%p",pageDict] ]; }
  • 17. 目次構造の取得 Document management — Portable document format — Part 1: PDF 1.7 より
  • 18. PDF 文書構造(1) CGPDFDictionaryRef catalog=CGPDFDocumentGetCatalog( document_ ); CGPDFDictionaryRef outlines=NULL; CGPDFDictionaryGetDictionary(catalog, "Outlines", &outlines ); // 先頭の要素を取得 CGPDFDictionaryRef first = NULL; CGPDFDictionaryGetDictionary(outlines, "First", &first ); // 見出しを取得 CGPDFStringRef title; CGPDFDictionaryGetString ( first, "Title", &title ); // 次の章 (cdr 部 ) を取得 CGPDFDictionaryRef next = NULL; CGPDFDictionaryGetDictionary(outlines, "Next", &next); // 小見出し( car 部)を取得 CGPDFDictionaryRef children; CGPDFDictionaryGetString ( first, "First", &children);
  • 19. PDF 文書構造(2) // ページオブジェクトを取得 CGPDFDictionaryRef page; CGPDFDictionaryDictionary ( first, "D", &title ); // 「 D 」キーがなく、ページオブジェクトを直接参照できない場合 CGPDFStringRef dest; CGPDFDictionaryGetString(dict, "Dest", &dest );
  • 20. Document management — Portable document format — Part 1: PDF 1.7 より
  • 21. ページ番号と文書構造のリンク val key 0 1 2 3 ・ ・ ・ n Pages Contents
  • 22. 文字列抽出機能 • コンテントストリームのなかから、文字 列描画命令部分を取り出す
  • 24. PDF のオペレータ param1 param2 param3 param4 op • 後置記法 • パラメータは LIFO スタックに積まれる param4 param3 param2 param1
  • 25. PDF の文字列描画 BT % Begin Text /F1 24 Tf % フォント指定 % /F1 がフォントを表現するシンボ ル 1 0 0 1 72 648 Tm % 描画位置の指定 (Hello World) Tj % 文字列描画 -- (と )が引用符 1 0 0 1 72 612 Tm % non-ASCII 文字列 <4D53835383568362834E3234837C834383938367> Tj 1 0 0 1 72 576 Tm 0.5 g % グレイスケール <82BB82EA82F08A44904682C982B582BD82E082CC> Tj ET % End Text 「 PDF by Hand 」 http://www.kobu.com/doc s/pdf/pdfxhand.htm より
  • 27. 文字列抽出 // コールバック関数を設定する CGPDFOperatorTableRef table_; CGPDFOperatorTableSetCallback(table_, "BT",stringBlockBeginsCallback); CGPDFOperatorTableSetCallback(table_, "ET", stringBlockEndedCallback); CGPDFOperatorTableSetCallback(table_, "TJ", stringArrayCallback); CGPDFOperatorTableSetCallback(table_, "Tj", stringCallback); CGPDFOperatorTableSetCallback(table_, "Tf", fontCallback); // ページに適用 CGPDFContentStreamRef contentStream = CGPDFContentStreamCreateWithPage(page); CGPDFScannerRef scanner = CGPDFScannerCreate(contentStream, table_, self); // userinfo として self を指定 bool ret = CGPDFScannerScan(scanner);
  • 28. 文字列抽出コールバック static void stringCallback(CGPDFScannerRef inScanner, void *userInfo) { PDFStringExtractor *zelf = (PDFStringExtractor *)userInfo; CGPDFStringRef string=NULL; if(CGPDFScannerPopString(inScanner, &string)) { // ↑LIFO なのでポップする // 座標関連の命令を取り出すときは注意 NSString* s = [zelf stringWithPDFString:string];
  • 29. 文字列抽出コールバック static void stringCallback(CGPDFScannerRef inScanner, void *userInfo) { PDFStringExtractor *zelf = (PDFStringExtractor *)userInfo; CGPDFStringRef string=NULL; if(CGPDFScannerPopString(inScanner, &string)) { // ↑ 全然文字列じゃない!!! NSString* s = [zelf stringWithPDFString:string];
  • 31. CID • PDF における " 文字列 " は、実際には CID の列で あることがある • CID= グリフ ( 字形 ) を一意に識別するための ID • CID と文字コードのマッピングは文字列描画に用 いるフォントによって異なる
  • 32. フォント指定が重要 BT % Begin Text /F1 24 Tf % フォント指定 % /F1 がフォントを表現するシンボ ル 1 0 0 1 72 648 Tm % 描画位置の指定 (Hello World) Tj % 文字列描画 -- (と )が引用符 1 0 0 1 72 612 Tm % non-ASCII 文字列 <4D53835383568362834E3234837C834383938367> Tj 1 0 0 1 72 576 Tm 0.5 g % グレイスケール <82BB82EA82F08A44904682C982B582BD82E082CC> Tj ET % End Text 「 PDF by Hand 」 http://www.kobu.com/doc s/pdf/pdfxhand.htm より
  • 33. CGPDFDictionaryRef pageDict = CGPDFPageGetDictionary(page); CGPDFDictionaryRef resourceDict = NULL; CGPDFDictionaryRef fontDict = NULL; // フォント辞書をスキャン if(CGPDFDictionaryGetDictionary(pageDict, "Resources", &resourceDict ) ) { if(CGPDFDictionaryGetDictionary(resourceDict, "Font", &fontDict ) ) { CGPDFDictionaryApplyFunction(fontDict,enumerateFontsInDictionary,se lf); } } static void enumerateFontsInDictionary(const char *key, CGPDFObjectRef value, void *info) { // フォント情報をキャッシュする }
  • 34. フォントのエンコーディング情報 • Encoding • "Identity-H","Identity-V" • DescendantFont • /Registry (Adobe) • /Ordering (Japan-1) • /Supplement (6) • CMAP 名
  • 35. CID ファイル :EUC-H の例 100 begincidrange ← 100 個の区間があることを示す <20> <7e> 231 ← cid231 〜 313 は printable ASCII の区間 <8ea0> <8edf> 326 <a1a1> <a1fe> 633 <a2a1> <a2ae> 727 <a2ba> <a2c1> 741 . . . endcidrange
  • 36.
  • 37. 課題 • 対応できてないパターンがある • テキスト領域認識 • 全文検索
  • 38. 参考文献 • Life is Beautiful ( 中島聡氏 ) • CloudReaders の開発 • PDF レンダリングのメモリ消費の問題 を指摘 • 超巨大ページにも対応 • 木下誠氏のマイコミジャーナルの記事 • Core Text を用いた CID→Unicode の簡便 な解決案が提示されています • http://news.mynavi.jp/column/iphone/03 9/index.html
  • 39. 参考文献 (2) • 通称フグ本 • CID などアドビ社の多国 語対応の情報 • 鈍器としても使えます
  • 40. 参考文献 (3) • もっと早く出ていれ ば。。。