iOS улучшает скорость рендеринга PDF - PullRequest
3 голосов
/ 29 мая 2011

Я пишу приложение, которое управляет документами для пользователя и (в конечном итоге) публикует файлы PDF, которые раздаются через веб-сервис на iPhone / iPad. Это почти исключительно отсканированные файлы PDF, и они, по-видимому, ПО-НАСТОЯЩЕМУ сводят на нет устройство iOS.

Первое решение, которое я придумал, состояло в том, чтобы просто разместить PDF в UIWebView. Это действительно очень хорошо работает для «сгенерированных» PDF-файлов, но НЕ для отсканированных PDF-файлов (я полагаю, что здесь разница между растром и вектором?).

Моим следующим решением было реализовать UIDocumentInteractionController, который, как говорили, увеличил ловкость. Я могу сообщить, что он действительно работает быстрее, чем UIWebView, но все еще неприемлемо медленно, даже для небольших двухстраничных PDF-файлов. (Кстати, функция «автооткрытие в другом приложении» вместе со встроенной печатью очень удобна!)

Я прочитал пост или 2 о фреймворке QuickLook, и я планирую разобраться в этом, но я также наткнулся на несколько постов, рассказывающих о классах CGPDFDocument и подобных. Похоже, они лучше контролируют навигацию по документам (в формате xPdf), но я не знаю, с чего начать. Кроме того, я даже не уверен, дает ли это преимущество в производительности для того, что я делаю.

Итак, первый вопрос: какой самый быстрый способ рендеринга отсканированных файлов PDF на iPhone / iPad?

Второй вопрос: отсканированные файлы PDF создаются моей компанией, поэтому я могу контролировать параметры создания PDF. Кто-нибудь знает, какие настройки могут улучшить скорость загрузки PDF-файлов на основе изображений?

Спасибо!

(Кстати: я кодировал сегодня 19 часов подряд, так что, если я бродил или не имел смысла, пожалуйста, прости меня! :))

Ответы [ 5 ]

6 голосов
/ 07 мая 2012

Самым быстрым решением будет написать свой собственный анализатор pdf и среду рендеринга с использованием классов CGPDFDocument. Секрет сверхбыстрого рендеринга в PDF заключается в использовании таких методов, как:

  • Вне экрана рендеринг полноразмерных страниц в изображения.
  • Активировать чертеж CATiledLayer можно только после определенного уровня масштабирования. Когда пользователь просматривает вашу PDF-страницу с уровнем масштабирования по умолчанию, нет необходимости активировать чертеж CATiledLayer, потому что это очень дорого. Просто отобразите уже закадровое изображение. Когда пользователь начинает увеличивать изображение, вы можете активировать CATiledLayer.
  • Использование интеллектуального алгоритма для кэширования закадровых отображаемых страниц PDF. Вы можете кэшировать предыдущую и следующую страницы как изображения за пределами экрана.
  • На быстрых устройствах (iPhone 4 или более поздней версии и iPad 2 или более поздней версии) вы можете запустить фоновое задание, которое будет выводить все страницы за пределы экрана и сохранять их на диск.
  • Кэширование регулярно использует информацию о pdf-страницах, например: исходный прямоугольник, поворот, повернутый прямоугольник и т. Д.
  • Вы будете использовать много объектов CGPDFPageRef. Важно знать, что это значительно увеличит использование памяти. Небольшая хитрость заключается в закрытии и повторном открытии объекта CGPDFDocumentRef при получении предупреждения о памяти.

Я использовал все вышеупомянутые приемы в PDFTouch SDK для iOS , разработанной мной быстрой платформой рендеринга PDF!

2 голосов
/ 02 августа 2011

Вы можете попытаться уменьшить размер изображения.Большие PDF-файлы действительно расширяют возможности iPad / iPhone.Конечно, это означает, что вам нужно рисовать / управлять PDF самостоятельно с помощью вызовов Quartz.

Большая скорость возможна при правильном кэшировании.Вы можете отображать страницы вне экрана и отображать их, не открывая фактический pdf - что намного, намного быстрее.

1 голос
/ 07 октября 2011

Используя UIWebView для рендеринга PDF, мы не получим должного контроля над PDF. как мы не можем перейти на нужную страницу напрямую. и мы не можем найти конкретное слово и выделить.

лучше использовать классы CGPDF, такие как CGPDFDocumentRef и CGPDFPageRef, для правильной обработки PDF-документов.

Используя эти классы, у нас есть два варианта для работы с PDF. 1. Извлечение PDF-страниц в виде изображений по отдельности и отображение с использованием UIImageView. 2. Извлеките содержимое каждой страницы с помощью CGPDFPageRef и создайте pdf для каждой страницы во время выполнения и отобразите в веб-представлении (лучший контроль над pdf и аккуратным отображением)

ниже приведен пример кода для извлечения отдельной страницы в виде изображения.

-(UIImage *)getPage : (NSString*) filePath{

    const char *myBuffer           = (const char*)filePath;                        // PDF Path
    CFStringRef urlString          = (CFStringRef)myBuffer;
    CFURLRef url                   = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, urlString, 2, NO);  
    CGPDFDocumentRef myDocumentRef = CGPDFDocumentCreateWithURL(url);

    CGPDFPageRef myPageRef         = CGPDFDocumentGetPage(myDocumentRef, 1);
    CGRect pdfcropBox              = CGPDFPageGetBoxRect(myPageRef,kCGPDFCropBox); //kCGPDFCropBox

    UIGraphicsBeginImageContext      (pdfcropBox.size);
    CGContextRef context           = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM            (context,0,pdfcropBox.size.height);// [self pageRect].origin.x,[self pageRect].origin.y+[self pageRect].size.height); //320);
    // scale 1:1 100%
    CGContextScaleCTM                (context, 1.0, -1.0);
    CGContextSaveGState              (context);
    CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(myPageRef, kCGPDFCropBox, CGRectMake(0, 0, pdfcropBox.size.width,pdfcropBox.size.height), 0, true);  //
    CGContextConcatCTM               (context, pdfTransform);
    CGContextDrawPDFPage             (context, myPageRef);
    CGContextRestoreGState           (context);

    UIImage *resultingImage        = UIGraphicsGetImageFromCurrentImageContext();  
    UIGraphicsEndImageContext        ();
    CGPDFDocumentRelease             (myDocumentRef);

    //CGPDFPageRelease(myPageRef);
        //myPageRef   = nil;
    myDocumentRef = nil;
    urlString     = nil;
    url           = nil;
    return resultingImage;
}
1 голос
/ 24 августа 2011

если вы в отчаянии, вы можете повторно обработать pdf-файлы на вашем сервере, чтобы превратить их в простые файлы изображений (связанные с исходными pdf-файлами), а затем загрузить их. таким образом, никакой разбор "pdf" не должен иметь место. а затем вы можете разместить на сервере или включить в качестве части приложения, если объем низкий.

В основном вам нужен серверный скрипт, который выполняет всю повторную обработку и помещает новые файлы в специальную папку. Может быть, вы делаете базу данных для ссылки на новые файлы. или, может быть, вы создаете имя каталога для каждого нового файла, который отражает исходное имя файла PDF.

0 голосов
/ 19 января 2016

Вот мои 2 цента о простом и быстром рендеринге PDF в Swift.

SwiftyPDF

  • Пейджинг с системой UIPageViewController
  • Масштабирование с функциями масштабирования UIScrollView
  • Рендеринг PDF быстро путем преобразования страницы в изображение-заполнитель
  • PDF-страница масштабируется и разбивается на маленькие плитки. Плитки кэшируются в файлы изображений и отображаются поверх изображения заполнителя (с использованием CATiledLayer)

Все еще WIP

...