আইফোন / আইপ্যাড / আইওএস-এর জন্য দ্রুত এবং জোঁক পিডিএফ ভিউয়ার - টিপস এবং ইঙ্গিত?


368

পিডিএফ আঁকার বিষয়ে সম্প্রতি অনেক প্রশ্ন এসেছে।

হ্যাঁ, আপনি খুব সহজেই পিডিএফ এর রেন্ডার করতে পারেন UIWebViewতবে এই পোষাকটি এমন কার্য সম্পাদন এবং কার্যকারিতা দেয় যা আপনি কোনও ভাল পিডিএফ দর্শকের কাছ থেকে আশা করতে পারেন expect

আপনি একটি PDF পৃষ্ঠা আহরণ করতে পারে একটি CALayer করতে বা একটি UIImage করতেএকটি জুম্যাবল ইউআইএসক্রোলভিউতে কীভাবে একটি বৃহত পিডিএফ আঁকবে তা দেখানোর জন্য অ্যাপলের কাছে স্যাম্পল কোডও রয়েছে

কিন্তু একই বিষয় ক্রপ আপ রাখা।

ইউআইআইমেজ পদ্ধতি:

  1. পিডিএফ UIImageকোনও স্তরগত পদ্ধতির পাশাপাশি অপটিক্যাল স্কেল নয়।
  2. CPU ও মেমরি উৎপাদিত উপর আঘাত UIImagesA থেকে PDFcontext এটা ব্যবহার করে একটি রিয়েল-টাইম নতুন জুম-স্তরের রেন্ডার তৈরি করতে সীমা / বাধা দেয়।

ক্যাটালেড লেয়ার পদ্ধতি:

  1. একটি পূর্ণ পিডিএফ পৃষ্ঠা আঁকতে একটি উল্লেখযোগ্য ওভারহেড (সময়) CALayerথের করে: স্বতন্ত্র টাইলস রেন্ডারিং করতে দেখা যায় (এমনকি একটি টাইলসাইজ টুইঙ্ক দিয়েও)
  2. CALayers সময়ের আগে প্রস্তুত করা যায় না (অফ স্ক্রিনে উপস্থাপিত)।

সাধারণত পিডিএফ দর্শকদের স্মৃতিশক্তি খুব ভারী হয়। এমনকি অ্যাপলের চিড়িয়াখানাযোগ্য পিডিএফ উদাহরণের মেমরি ব্যবহার নিরীক্ষণ করুন।

আমার বর্তমান প্রকল্পে, আমি একটি পিডিএফ ভিউয়ার বিকাশ করছি এবং UIImageএকটি পৃষ্ঠার একটি পৃথক থ্রেডে পেশ করছি (সমস্যাগুলি এখানেও!) এবং স্কেলটি এক্স 1 হওয়ার সময় এটি উপস্থাপন করছি। CATiledLayerস্কেল একবারে কিক্সের রেন্ডারিং> 1। আইবুকস অনুরূপ ডাবল টেক অ্যাপ্রোচ গ্রহণ করে যেমন আপনি পৃষ্ঠাগুলি স্ক্রোল করে দেখেন যে আপনি একটি খাস্তা সংস্করণ প্রকাশের আগে মাত্র এক সেকেন্ডেরও কম সময়ের জন্য পৃষ্ঠার একটি নিম্ন রেস সংস্করণ দেখতে পাবেন।

আমি ফোকাসে পৃষ্ঠার প্রতিটি পাশে 2 পৃষ্ঠাগুলি রেন্ডার করছি যাতে পিডিএফ চিত্রটি অঙ্কন শুরু হওয়ার আগে স্তরটি মাস্ক করার জন্য প্রস্তুত P পৃষ্ঠাগুলি যখন ফোকাস করা পৃষ্ঠা থেকে +2 পৃষ্ঠা দূরে থাকে তখন আবার ধ্বংস হয়।

অঙ্কন পিডিএফের পারফরম্যান্স / মেমরি হ্যান্ডলিংয়ের উন্নতি কতটা ছোট বা প্রকট হোক না কেন কারও কাছে অন্তর্দৃষ্টি আছে? বা এখানে অন্য কোন বিষয় নিয়ে আলোচনা হয়েছে?

সম্পাদনা: কিছু টিপস (ক্রেডিট- লুক ম্যাকিনিস, ভিডেসমেডটি, ম্যাট গ্যালাগার, জোহান):

  • আপনি যখন পারেন কোনও ডিস্কে মিডিয়া সংরক্ষণ করুন।

  • যদি টাইললেয়ারগুলিতে রেন্ডারিং হয় তবে বড় টাইলসাইজ ব্যবহার করুন

  • init প্রায়শই স্থানধারক অবজেক্টগুলির সাথে অ্যারে ব্যবহার করে, পর্যায়ক্রমে অন্য ডিজাইনের পদ্ধতির মধ্যে এটি

  • নোট করুন যে চিত্রগুলি একটির চেয়ে দ্রুততর রেন্ডার হবে CGPDFPageRef

  • সময়ের আগে পৃষ্ঠাগুলি প্রস্তুত করতে NSOperationsজিসিডি ও ব্লক ব্যবহার করুন ।

  • অঙ্কন করার সময় মেমরির ব্যবহার হ্রাস করার CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault);আগে কল করুনCGContextDrawPDFPage

  • ডকরাফ দিয়ে আপনার NSOperationsআরম্ভ করা একটি খারাপ ধারণা (স্মৃতি), ডকফেরাফটিকে একটি সিঙ্গেলনে আবদ্ধ করুন।

  • অযথা বাতিল করুন NSOperationsযখন আপনি পারবেন, বিশেষত যদি তারা স্মৃতি ব্যবহার করে থাকে তবে প্রসঙ্গটি উন্মুক্ত রেখে সতর্ক থাকুন!

  • পৃষ্ঠা অবজেক্টগুলি পুনর্ব্যবহার করুন এবং অব্যবহৃত দর্শনগুলি ধ্বংস করুন

  • যে কোনও উন্মুক্ত প্রসঙ্গগুলি আপনার প্রয়োজন না হওয়ার সাথে সাথেই তা বন্ধ করুন

  • মেমোরি সতর্কতা গ্রহণ করার পরে ডকরাফ এবং যে কোনও পৃষ্ঠা ক্যাশে প্রকাশ এবং পুনরায় লোড করুন

অন্যান্য পিডিএফ বৈশিষ্ট্য:

নথিপত্র

উদাহরণ প্রকল্প



+1 এবং এই সমস্ত তথ্য যুক্ত করার জন্য ধন্যবাদ, আমি যখন আমার পাঠক বিকাশ করছিলাম তখন তা আমার কাছে থাকত;) এছাড়াও পিডিএফ টিকা সম্পর্কে আমার প্রশ্ন যুক্ত করার জন্য ধন্যবাদ (এতে নমুনা কোড সহ উত্তরগুলিও রয়েছে)। কিছু দিন আগে আমি এটি খুললাম: stackoverflow.com/questions/4097044/pdf-search-on-the- আইফোন আপনার কাছে কোনও পরামর্শ আছে?
pt2ph8

আমি এখনও এটিকে আমার কাছে আবৃত করি নি তাই এলোমেলো ধারণাগুলি ব্লগটিতে আপনাকে নির্দেশ করা ছাড়া আমি আর কিছুই বলতে পারি না: এলোমেলো-.net.asp / posts / 42 পোস্টটির জন্য ধন্যবাদ যদিও আমি সমস্ত পিডিএফ ইস্যু একত্রিত করার চেষ্টা করছি জায়গা।
লুক ম্যাকিনিइस

8
আমার সংস্থায় আমরা পিডিএফ রেন্ডারিং, স্বরলিপি ইত্যাদির জন্য একটি তৃতীয় পক্ষের সমাধান হিসাবে ব্যবহার করেছি PSPDFKit, এটি সস্তা নয়, তবে মূল্যবান: pspdfkit.com
জ্যানোস

1
+1 আমি আমার ওপেন সোর্স পিডিএফ ভিউয়ারের জন্য এই দরকারী টিপসগুলি অনুসরণ করেছি পিডিএফ পিডিএফ github.com/prcela/SwiftyPDF
প্রেসেলা

উত্তর:


103

আনুমানিকভাবে একই পদ্ধতির সাহায্যে আমি এ জাতীয় অ্যাপ্লিকেশন তৈরি করেছি:

  • আমি ডিস্কে উত্পন্ন চিত্রটি ক্যাশে করি এবং সর্বদা পৃথক থ্রেডে দুই থেকে তিনটি চিত্র আগে থেকেই উত্পন্ন করি।
  • আমি একটি দিয়ে ওভারলে করি না UIImageতবে জুমিংয়ের পরে স্তরটিতে চিত্রটি আঁকুন 1 যখন মেমরির সতর্কতা জারি করা হয় তখন এই টাইলগুলি স্বয়ংক্রিয়ভাবে প্রকাশিত হবে।

যখনই ব্যবহারকারী জুম করা শুরু করবেন, আমি CGPDFPageযথাযথ সিটিএম ব্যবহার করে এটি অর্জন এবং রেন্ডার করি। কোডটি এর - (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
এর জন্য অনেক ধন্যবাদ, এবং সিজিপিডিএফডোকামেন্টরেফ ক্যাশিং সম্পর্কে টিপস।
লুক ম্যাকিনিइस

মাত্র একটি তাত্ক্ষণিক প্রশ্ন: স্কেল 1.0 হয় যখন আপনি পিডিএফপেজআরফ পাচ্ছেন এবং রূপান্তর করছেন কেন? কারণ আমি দেখতে পাচ্ছি যে আপনি ট্রান্সফর্মটি তৈরি করার আগে আপনি একটি বেসআইমেজ (বিজি ওয়ার্কারের চিত্র?) আঁকেন।
লুক ম্যাকিনিइस

@ লুক: আপনি যে কোনও পারফরম্যান্স উন্নতি করতে পারেন তা এখানে পোস্ট করুন। ধন্যবাদ !
VdesmedT

67

একটি সহজ এবং কার্যকর পিডিএফ দর্শকের জন্য, যখন আপনার কেবল সীমাবদ্ধ কার্যকারিতা প্রয়োজন হয়, আপনি এখন (আইওএস 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];

হ্যাঁ, এটি ইউআইবিউবভিউ ব্যবহার করার মত ধারণাগতভাবে একই। সিজিপিডিএফ * জিনিসগুলি কীভাবে সহজে ব্যবহার করতে হয় তা নির্ধারণের জন্য আমরা ঘন্টাগুলি ব্যয় করব না।
pt2ph8

5
হ্যা অবশ্যই. আমি অবশ্যই এটি একটি সম্পূর্ণ সমাধান হিসাবে উপস্থাপন করি না। তবে এই প্রশ্নের কিছু পাঠক সচেতন নাও হতে পারে যে কিছু উদ্দেশ্যে, এটি একটি যুক্তিসঙ্গত সমাধান। এটি পরিষ্কার করার জন্য উত্তর আপডেট করেছেন।
জোশুয়া জে ম্যাককিনন

6
এই জন্য +1। আমার প্রাথমিক আগ্রহটি হল পিডিএফ ফর্ম্যাটে থাকা কিছু অ্যাপ্লিকেশন ডকুমেন্টেশনগুলি ব্যবহারকারীকে দেখার অনুমতি দেওয়া। আমি অনুসন্ধান, হাইলাইট বা অন্য ঘণ্টা এবং হুইসেলগুলির কোনও বিষয়েই যত্ন নিই না - কেবল পারফরম্যান্ট পিডিএফ উপস্থাপনা।
স্মরণে

2
আমার ইউআইআইমেজ + পিডিএফ বিভাগটি ক্যাশেিং লেয়ারে অন্তর্নির্মিত একটি দ্রুত নন-বাজে পিডিএফ রেন্ডারার। github.com/mindbrix/UIImage-PDF
Mindbrix

6

আইওএস ১১-এর পর থেকে , আপনি পিডিএফগুলি প্রদর্শন এবং পরিচালনা করার জন্য পিডিএফকিট নামক নেটিভ কাঠামোটি ব্যবহার করতে পারেন ।

পিডিএফকিট আমদানি করার পরে, আপনার 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)
}

অ্যাপল বিকাশকারী ডকুমেন্টেশনে পিডিএফকিট সম্পর্কে আরও পড়ুন।


-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);
     } }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.