[解決済み】iPhone/iPad/iOS用の高速で無駄のないPDFビューア - ヒントとヒント?
質問
最近、PDFの描画に関する質問が多いのですが。
そうです。
UIWebView
しかし、これでは優れたPDFビューアーに期待されるようなパフォーマンスや機能性を得ることはできません。
PDFのページを描画することができます をCALayerに または をUIImageに変換します。 . Apple には、大きな PDF を描画する方法を示すサンプルコードもあります。 ズーム可能なUIScrollviewで
しかし、同じ問題が何度も出てきます。
UIImageメソッド。
-
PDFの
UIImage
光学的には は、レイヤーアプローチと同様に拡大縮小が可能です。 -
を生成する際のCPUとメモリの負荷が大きい。
は
UIImages
からPDFcontext
を作成するために使用することを制限/防止します。 新しいズームレベルのリアルタイムレンダリング。
CATiledLayerメソッド。
-
大きなオーバーヘッド(時間)が発生する
PDFの全ページを
CALayer
: 個々のタイルのレンダリングが確認できる (tileSize を調整した場合でも) -
CALayers
事前に用意できない 時間(画面外にレンダリングされる)。
一般的にPDFビューワーはメモリもかなり重いです。アップルのズーム可能なPDFの例のメモリ使用量をモニターしてもわかるでしょう。
現在のプロジェクトでは、PDFビューアを開発しています。
UIImage
のページを別スレッドで表示し(ここでも問題!)、スケールをx1にして表示しています。
CATiledLayer
iBooksでは、ページをスクロールすると、低解像度のページが1秒弱表示された後、鮮明なバージョンが表示されるという、二重の意味で似たようなアプローチを取っています。
フォーカスしたページの両側に2ページずつレンダリングして、PDF画像が描画を開始する前にレイヤーをマスクする準備ができるようにしています。
どなたか、Drawing PDFのパフォーマンスやメモリ処理を改善するために、どんな小さなことでも、あるいは明白なことでも、何か見識をお持ちですか? または、ここで議論されている他の問題でもかまいません。
EDIT いくつかのヒント(クレジット- Luke Mcneice,VdesmedT,Matt Gallagher,Johann):
-
可能な限り、メディアをディスクに保存してください。
-
TiledLayersでレンダリングする場合は、より大きなtileSizesを使用します。
-
は、頻繁に使用される配列をプレースホルダオブジェクトで開始します。 これ
-
を使用するよりも、画像の方がレンダリングが速くなることに注意してください。
CGPDFPageRef
-
使用方法
NSOperations
またはGCD &を使用してください。 ブロック を使用して、事前にページを準備します。 を使用します。 -
コール
CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault);
以前CGContextDrawPDFPage
描画時のメモリ使用量を減らすために -
イニシエーション
NSOperations
をdocRefで使用するのは悪い考えです(メモリ)。docRefをシングルトンにラップしてください。 -
不要な
NSOperations
できる限り、特にメモリを使う場合は、コンテキストを開いたままにしないように注意してください。 -
ページオブジェクトをリサイクルし、未使用のビューを破棄します。
-
開いているContextsが不要になったら、すぐに閉じる。
-
メモリの警告を受けたら、DocRefとあらゆるページのキャッシュを解放して再ロードします。
その他のPDFの機能。
-
PDF内のリンク取得 (そして ここで そして こちら )
-
リンク先の取得 (ページ番号の取得は
/Dest
配列)
-
CALayerとオフスクリーンレンダリング - 次のページをレンダリングし、高速でスムーズな表示を実現します。
ドキュメンテーション
- Quartz PDFObjects (メタ情報、注釈、サムネイルに使用します。)
- Abobe PDF仕様
プロジェクト例
-
アップル/ ZoomingPDF
- ズーミングを行います。
UIScrollView
,CATiledLayer
-
vfr/ リーダー
- ズーム、ページング
UIScrollView
,CATiledView
- 眉毛/葉 - ページングとトランジション
- / スキム - 見えるものすべて(OSX用PDFリーダー/エディタ)
解決方法は?
私は、このようなアプリケーションを、.を除いてほぼ同じアプローチで構築したことがあります。
- 生成された画像をディスクにキャッシュし、常に別スレッドで2~3枚の画像を事前に生成しています。
-
でオーバーレイしない。
UIImage
そのタイルは、メモリ警告が出たときに自動的に解放されます。
ユーザがズームを開始するたびに、私は
CGPDFPage
を作成し、適切な CTM を使用してレンダリングします。 のコードは
- (void)drawLayer: (CALayer*)layer inContext: (CGContextRef) context
は次のようなものです。
CGAffineTransform currentCTM = CGContextGetCTM(context);
if (currentCTM.a == 1.0 && baseImage) {
//Calculate ideal scale
CGFloat scaleForWidth = baseImage.size.width/self.bounds.size.width;
CGFloat scaleForHeight = baseImage.size.height/self.bounds.size.height;
CGFloat imageScaleFactor = MAX(scaleForWidth, scaleForHeight);
CGSize imageSize = CGSizeMake(baseImage.size.width/imageScaleFactor, baseImage.size.height/imageScaleFactor);
CGRect imageRect = CGRectMake((self.bounds.size.width-imageSize.width)/2, (self.bounds.size.height-imageSize.height)/2, imageSize.width, imageSize.height);
CGContextDrawImage(context, imageRect, [baseImage CGImage]);
} else {
@synchronized(issue) {
CGPDFPageRef pdfPage = CGPDFDocumentGetPage(issue.pdfDoc, pageIndex+1);
pdfToPageTransform = CGPDFPageGetDrawingTransform(pdfPage, kCGPDFMediaBox, layer.bounds, 0, true);
CGContextConcatCTM(context, pdfToPageTransform);
CGContextDrawPDFPage(context, pdfPage);
}
}
を含むオブジェクトです。
CGPDFDocumentRef
. にアクセスする部分を同期させています。
pdfDoc
プロパティを解放し、memoryWarningを受信したときに再作成しているからです。 どうやら
CGPDFDocumentRef
オブジェクトが内部キャッシュを行うのですが、それを取り除く方法が見つかりませんでした。
関連
-
[解決済み] 基本的なUIButtonをプログラムで作成するには?
-
[解決済み] <UITabBarController: 0x197870> の外観遷移の開始/終了の呼び出しがアンバランスである。
-
[解決済み] MacOSとXcodeをアップデートすると、Xcode 8.1の「No matching provisioning profiles found」が表示される。
-
[解決済み] ERROR ITMS-9000: "Redundant Binary Upload. 列車 '1.0' のビルドバージョン '1.0' のバイナリアップロードが既に存在します" と表示されました。
-
[解決済み] iOS HTTP GET リクエストを実行できません -Error Domain=NSURLErrorDomain Code=-1012
-
[解決済み] ios8ではdidRegisterForRemoteNotificationsWithDeviceTokenは呼ばれないが、didRegister...Settingsは呼ばれる。
-
[解決済み] 脱獄したiphoneで`uicache`コマンドは何をするのですか?[クローズド]
-
[解決済み] viewDidLoad()は何のためにあるのですか?[重複]する
-
[解決済み] Xcode 6: iOS 8.1 The Developer Disk Imageをマウントできませんでした。
-
[解決済み】iPadとiPhoneの入力ボタンのスタイル変更について
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 libc++abi.dylib: NSException 型のキャッチできない例外で終了する (lldb)
-
[解決済み] ペン先を読み込んだが、「表示」コンセントが設定されていない
-
[解決済み] Int 型のインデックスを持つ [AnyObject]? の値を添え字として使用できません。
-
[解決済み] iPhoneが使用できません。デバイスを再接続してください
-
[解決済み] 基本的なUIButtonをプログラムで作成するには?
-
[解決済み] UTF-8でエンコードされたNSDataをNSStringに変換します。
-
[解決済み] Swiftを使って音を鳴らすには?
-
[解決済み] iOS HTTP GET リクエストを実行できません -Error Domain=NSURLErrorDomain Code=-1012
-
[解決済み] アプリケーションは、アプリケーション起動の最後にルートビューコントローラーを持つことが期待される
-
[解決済み] CFBundleVersionとCFBundleShortVersionStringには、どのような値を使用すればよいですか?