Преобразование PDF в UIImageView
Я нашел код, который дает мне UIImage
из PDF файла. Он работает, но у меня есть два вопроса:
- Есть ли возможность достичь лучшего качества UIImage? (См. Скриншот)
- Я вижу только первую страницу в
UIImageView
. Должен ли я вставлять файл в UIScrollView
для завершения?
- Или лучше отображать только одну страницу и использовать кнопки для навигации по страницам?
P.S. Я знаю, что UIWebView
может отображать PDF-страницы с некоторыми функциями, но мне это нужно как UIImage
или по крайней мере в UIView
.
Bad quality Image:
![Bad quality Image]()
Code:
-(UIImage *)image {
UIGraphicsBeginImageContext(CGSizeMake(280, 320));
CGContextRef context = UIGraphicsGetCurrentContext();
CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("ls.pdf"), NULL, NULL);
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
CGContextTranslateCTM(context, 0.0, 320);
CGContextScaleCTM(context, 1.0, -1.0);
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 4);
CGContextSaveGState(context);
CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, CGRectMake(0, 0, 280, 320), 0, true);
CGContextConcatCTM(context, pdfTransform);
CGContextDrawPDFPage(context, page);
CGContextRestoreGState(context);
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resultingImage;
}
Ответы
Ответ 1
Что вы делаете с вызовом CGContextTranslateCTM(context, 0.0, 320);
?
Вы должны извлечь правильные метрики в формате pdf, с таким кодом:
cropBox = CGPDFPageGetBoxRect(page, kCGPDFCropBox);
rotate = CGPDFPageGetRotationAngle(page);
Кроме того, как вы видите, в pdf может быть информация о ротации, поэтому вам нужно использовать CGContextTranslateCTM/CGContextRotateCTM/CGContextScaleCTM
в зависимости от угла.
Вы также можете захотеть скопировать любой контент, который находится за пределами области CropBox
, так как в pdf есть различные viewPorts
, которые вы обычно не хотите отображать (например, для принтеров, чтобы возможна полная печать) → use CGContextClip
.
Затем вы забываете, что в справочнике pdf задается белый цвет фона. Есть много документов, которые не определяют какой-либо фоновый цвет вообще - вы получите странные результаты, если вы не нарисуете белый фон самостоятельно → CGContextSetRGBFillColor
и CGContextFillRect
.
Ответ 2
Я знаю, что немного опоздал, но я надеюсь, что смогу помочь кому-то еще найти ответ.
Что касается заданных вопросов:
-
Я боюсь, что единственный способ добиться лучшего качества изображения - сделать большее изображение и позволить UIImageView
изменить его размер для вас. Я не думаю, что вы можете установить разрешение, но использование большего изображения может быть хорошим выбором. Для страницы не потребуется слишком много времени, и изображение будет иметь лучшее качество. PDF файлы отображаются по запросу в зависимости от уровня масштабирования, поэтому они, похоже, имеют "лучшее качество".
-
Что касается рендеринга всех страниц, вы можете получить количество страниц в документе, вызывающих CGPDFDocumentGetNumberOfPages( pdf )
, и используя простой цикл for
, вы можете конкатрировать все изображения, созданные на одном изображении. Для его отображения используйте UIScrollVIew
.
-
На мой взгляд, этот подход лучше, чем выше, но вы должны попытаться его оптимизировать, например, всегда отображая текущую, предыдущую и следующую страницу. Для хороших эффектов перехода прокрутки, почему бы не использовать горизонтальный UIScrollVIew
.
Для более общего кода рендеринга я всегда делаю поворот следующим образом:
int rotation = CGPDFPageGetRotationAngle(page);
CGContextTranslateCTM(context, 0, imageSize.height);//moves up Height
CGContextScaleCTM(context, 1.0, -1.0);//flips horizontally down
CGContextRotateCTM(context, -rotation*M_PI/180);//rotates the pdf
CGRect placement = CGContextGetClipBoundingBox(context);//get the flip placement
CGContextTranslateCTM(context, placement.origin.x, placement.origin.y);//moves the the correct place
//do all your drawings
CGContextDrawPDFPage(context, page);
//undo the rotations/scaling/translations
CGContextTranslateCTM(context, -placement.origin.x, -placement.origin.y);
CGContextRotateCTM(context, rotation*M_PI/180);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextTranslateCTM(context, 0, -imageSize.height);
Steipete уже упомянул установку белого фона:
CGContextSetRGBFillColor(context, 1, 1, 1, 1);
CGContextFillRect(context, CGRectMake(0, 0, imageSize.width, imageSize.height));
Итак, последнее, что нужно иметь в виду, - это экспортировать изображение, установить максимальное значение. Например:
UIImageJPEGRepresentation(image, 1);