IPhone / iPad / iOs के लिए फास्ट और लीन पीडीएफ व्यूअर - टिप्स और संकेत?


368

PDF के ड्राइंग के बारे में हाल ही में कई प्रश्न आए हैं।

हां, आप पीडीएफ को बहुत आसानी से प्रस्तुत कर सकते हैं UIWebViewलेकिन यह केंट प्रदर्शन और कार्यक्षमता दे सकता है जो आप एक अच्छे पीडीएफ दर्शक से उम्मीद करेंगे।

आप एक पीडीएफ पेज को एक काइलेयर या एक UIImage के लिए आकर्षित कर सकते हैं । Apple के पास नमूना कोड भी है कि जूमने योग्य UIScrollview में एक बड़ी पीडीएफ कैसे बनाएं

लेकिन वही मुद्दे सामने आते रहते हैं।

UIImage विधि:

  1. पीडीएफ एक UIImageवैकल्पिक पैमाने पर और साथ ही एक परत दृष्टिकोण में नहीं है।
  2. सीपीयू और मेमोरी UIImagesएक PDFcontext सीमा से उत्पन्न होने पर हिट / नए ज़ूम-स्तरों के एक वास्तविक समय रेंडर बनाने के लिए इसका उपयोग करने से रोकता है।

CATiledLayer विधि:

  1. Theres एक महत्वपूर्ण ओवरहेड (समय) एक पूर्ण पीडीएफ पेज ड्राइंग करने के लिए एक CALayer: व्यक्तिगत टाइल्स प्रतिपादन देखा जा सकता है (यहां तक ​​कि एक टाइल आकार ट्विस्ट के साथ)
  2. CALayers खिचड़ी समय से पहले तैयार की जानी चाहिए (ऑफ-स्क्रीन प्रदान की गई)।

आम तौर पर पीडीएफ दर्शक मेमोरी पर भी भारी होते हैं। यहां तक ​​कि ऐप्पल के ज़ूम करने योग्य पीडीएफ उदाहरण के मेमोरी उपयोग की निगरानी करें।

अपनी वर्तमान परियोजना में, मैं एक पीडीएफ दर्शक विकसित कर रहा हूं और UIImageएक पृष्ठ को एक अलग थ्रेड में (यहां भी समस्याएँ!) प्रदान कर रहा हूं और इसे प्रस्तुत कर रहा हूं, जबकि स्केल ए 1 है। CATiledLayerस्केल> 1 में एक बार प्रतिपादन kicks। iBooks एक समान दोहरा दृष्टिकोण लेता है जैसे कि आप उन पृष्ठों को स्क्रॉल करते हैं जिन्हें आप एक कुरकुरा संस्करण प्रकट होने से पहले पृष्ठ के निचले रेस संस्करण को एक सेकंड से भी कम समय के लिए देख सकते हैं।

Im पेज के प्रत्येक पक्ष पर ध्यान में रखते हुए 2 पृष्ठों का प्रतिपादन करता है, ताकि आरेखण शुरू होने से पहले पीडीएफ छवि परत को मुखौटा करने के लिए तैयार हो जाए। ध्यान केंद्रित पृष्ठ से +2 पृष्ठ दूर होने पर फिर से नष्ट हो जाते हैं।

क्या किसी के पास कोई अंतर्दृष्टि है, कोई बात नहीं, ड्राइंग पीडीएफ के प्रदर्शन / मेमोरी हैंडलिंग में सुधार करने के लिए कितना छोटा या स्पष्ट है? या किसी अन्य मुद्दे पर यहाँ चर्चा की?

संपादित करें: कुछ सुझाव (क्रेडिट- ल्यूक मैकने, वेड्समेड्ट, मैट गैलाघर, जोहान):

  • किसी भी मीडिया को डिस्क में सेव करें जब आप कर सकते हैं।

  • अगर टाइल वाले पर रेंडरिंग करते हैं तो बड़ी टाइल का उपयोग करें

  • init अक्सर प्लेसहोल्डर वस्तुओं के साथ इस्तेमाल किया सरणियों, alternitively एक और डिजाइन दृष्टिकोण है इस एक

  • ध्यान दें कि चित्र एक से अधिक तेजी से प्रस्तुत करना होगा CGPDFPageRef

  • समय से पहले पृष्ठ तैयार करने के लिए NSOperationsजीसीडी और ब्लाकों का उपयोग करें ।

  • ड्राइंग करते समय मेमोरी का उपयोग कम करने CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault);से पहले कॉल करेंCGContextDrawPDFPage

  • docRef के NSOperationsसाथ आपका init'ing करना एक बुरा विचार (मेमोरी) है, docRef को एक सिंगलटन में लपेटें।

  • निरर्थक को रद्द करें NSOperationsजब आप कर सकते हैं, खासकर यदि वे स्मृति का उपयोग कर रहे होंगे, तो संदर्भों को खुला छोड़ने से सावधान रहें!

  • पृष्ठ ऑब्जेक्ट रीसायकल करें और अप्रयुक्त विचारों को नष्ट करें

  • जैसे ही आपको उनकी आवश्यकता नहीं है, किसी भी खुले संदर्भ को बंद करें

  • मेमोरी चेतावनियों को प्राप्त करने पर और डॉकर्फ और किसी भी पेज कैश को पुनः लोड करें

अन्य पीडीएफ विशेषताएं:

प्रलेखन

उदाहरण परियोजनाओं



+1 और इस सभी जानकारी को जोड़ने के लिए धन्यवाद, काश मेरे पास यह तब होता जब मैं अपने पाठक को विकसित कर रहा था;) पीडीएफ एनोटेशन के बारे में अपना प्रश्न जोड़ने के लिए भी धन्यवाद (इसमें नमूना कोड के साथ उत्तर भी शामिल हैं)। कुछ दिनों पहले मैंने इसे खोला: stackoverflow.com/questions/4097044/pdf-search-on-the-iphone क्या आपके पास कोई सुझाव है?
pt2ph8

मैंने अभी तक इसे कवर नहीं किया है, इसलिए मैं यादृच्छिक विचारों वाले ब्लॉग पर आपको इंगित करने के अलावा और कुछ नहीं कह सकता: random-ideas.net/posts/42 हालांकि इस पोस्ट के लिए धन्यवाद, Im एक में सभी पीडीएफ मुद्दों को इकट्ठा करने की कोशिश कर रहा हूं जगह।
ल्यूक मैकेनीस

8
मेरी कंपनी में हम Pdf रेंडरिंग, नोटेशन आदि के लिए उपयोग करते थे, जिसे 3rd पार्टी सॉल्यूशन कहा जाता है PSPDFKit, यह सस्ता नहीं है, लेकिन इसके लायक है: pspdfkit.com
János

1
+1 मैंने अपने खुले स्रोत के लिए इन उपयोगी युक्तियों का अनुसरण किया पीडीएफ दर्शक Swifty PDF github.com/prcela/SwiftyPDF
Prcela

जवाबों:


103

मैंने इस तरह के एप्लिकेशन का निर्माण किया है, सिवाय इसके कि यह एक ही दृष्टिकोण है:

  • मैं डिस्क पर उत्पन्न छवि को कैश करता हूं और हमेशा एक अलग धागे में अग्रिम में दो से तीन छवियां उत्पन्न करता हूं।
  • मैं ओवरले के साथ ओवरले नहीं करता, UIImageबल्कि ज़ूम करते समय परत में छवि को खींचता है। 1. वे टाइलें स्वचालित रूप से जारी की जाएंगी जब मेमोरी चेतावनी जारी की जाती है।

जब भी उपयोगकर्ता ज़ूम करना शुरू करता है, मैं 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संपत्ति का उपयोग करता हूं, क्योंकि मैं इसे जारी करता हूं और मेमोरीवर्जन प्राप्त करते समय इसे फिर से बनाता हूं। ऐसा लगता है कि CGPDFDocumentRefऑब्जेक्ट कुछ आंतरिक कैशिंग करता है जो मुझे नहीं मिला कि कैसे छुटकारा पाएं।


1
जब उपयोगकर्ता ज़ूम करना शुरू करता है तो आपका दृष्टिकोण क्या है?
ल्यूक मैकेनीस

2
@ ल्यूक: मैंने उत्तर पोस्ट करने के लिए संशोधित किया है
VdesmedT

1
इसके लिए बहुत बहुत धन्यवाद, और CGPDFDocumentRef कैशिंग के बारे में टिप।
ल्यूक मैकेनीस

बस एक त्वरित प्रश्न: क्यों आप pdfPageRef प्राप्त कर रहे हैं और जब पैमाने 1.0 है, तो क्या है? क्योंकि मैं देख रहा हूं कि आप ट्रांसफॉर्मेशन बनाने से पहले एक बेसइमेज (बीजी वर्कर से छवि?) खींचते हैं।
ल्यूक मैकेनीस

@ ल्यूक: कृपया द्वारा किए गए किसी भी प्रदर्शन में सुधार के बाद यहां पोस्ट करें। धन्यवाद !
VdesmedT

67

एक सरल और प्रभावी पीडीएफ दर्शक के लिए, जब आपको केवल सीमित कार्यक्षमता की आवश्यकता होती है, तो आप अब (iOS 4.0+) क्विकचुक फ्रेमवर्क का उपयोग कर सकते हैं:

सबसे पहले, आपको QuickLook.frameworkऔर के खिलाफ लिंक करने की आवश्यकता है#import <QuickLook/QuickLook.h>;

बाद में, viewDidLoadया तो आलसी आरंभीकरण विधियों में से किसी में:

QLPreviewController *previewController = [[QLPreviewController alloc] init];
previewController.dataSource = self;
previewController.delegate = self;
previewController.currentPreviewItemIndex = indexPath.row;
[self presentModalViewController:previewController animated:YES];
[previewController release];

हाँ, यह वैचारिक रूप से UIWebView का उपयोग करने के समान है। अगर यह आसान था तो हम सीजीपीडीएफ * सामान का उपयोग करने के लिए घंटों खर्च नहीं करेंगे।
pt2ph8

5
हां यकीनन। मैं निश्चित रूप से इसे पूर्ण समाधान के रूप में प्रस्तुत नहीं करता हूं। लेकिन इस सवाल के कुछ पाठकों को पता नहीं हो सकता है कि, कुछ उद्देश्यों के लिए, यह एक उचित समाधान है। स्पष्ट करने के लिए उत्तर को अपडेट करें।
जोशुआ जे। मैककिनन

6
इसके लिए +1। मेरी प्राथमिक रुचि उपयोगकर्ता को पीडीएफ प्रारूप में कुछ इन-ऐप प्रलेखन देखने की अनुमति देना है। मुझे खोज करने, हाइलाइट करने या अन्य किसी भी घंटी और सीटी के बारे में परवाह नहीं है - बस पीडीएफ पीडीएफ रेंडरिंग।
मेमोरियल जूल

2
मेरा UIImage + PDF श्रेणी एक त्वरित नो-नॉनसेंस पीडीएफ रेंडरर है जो बिल्ट इन कैशिंग लेयर के साथ है। github.com/mindbrix/UIImage-PDF
माइंडब्रिक्स

6

IOS 11 के बाद से , आप PDF को प्रदर्शित करने और हेरफेर करने के लिए PDFKit नामक मूल ढांचे का उपयोग कर सकते हैं ।

PDFKit आयात करने के बाद, आपको PDFViewस्थानीय या दूरस्थ URL के साथ आरंभ करना चाहिए और इसे अपने दृश्य में प्रदर्शित करना चाहिए।

if let url = Bundle.main.url(forResource: "example", withExtension: "pdf") {
    let pdfView = PDFView(frame: view.frame)
    pdfView.document = PDFDocument(url: url)
    view.addSubview(pdfView)
}

Apple डेवलपर डॉक्यूमेंट में PDFKit के बारे में और पढ़ें।


-2
 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);
     } }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.