将 PDF 加载到屏幕外图层
Posted
技术标签:
【中文标题】将 PDF 加载到屏幕外图层【英文标题】:Load PDF into layer offscreen 【发布时间】:2010-04-15 06:20:19 【问题描述】:有没有办法将 PDF 加载到屏幕外的 CALayer(或 CATiledLayer)中,然后在需要时显示它?该解决方案还应支持以所需分辨率进行缩放。
更新 只是为了澄清 - 我希望 pdf 保持基于矢量。
【问题讨论】:
请将它添加到您的问题中 - 您还想要缩放。 【参考方案1】:注意:您告诉过您需要将 PDF 加载到 CALayer 中。但是在这里,我有将整个 pdf 页面加载到图像中的解决方案。一旦图像进入数组,您可以在需要时查看其中的任何一个。如果您有任何疑问,请添加评论。
您只需复制并粘贴以下代码。它几乎对你有用。我已经测试过了。首先将以下方法放在视图控制器的实现之上。
NSMutableArray *aRefImgs; // global variable.
void setRefImgs(NSMutableArray *ref)
aRefImgs=ref;
NSMutableArray* ImgArrRef()
return aRefImgs;
CGPDFDocumentRef MyGetPDFDocumentRef (const char *filename)
CFStringRef path;
CFURLRef url;
CGPDFDocumentRef document;
path = CFStringCreateWithCString (NULL, filename,kCFStringEncodingUTF8);
url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, 0);
CFRelease (path);
document = CGPDFDocumentCreateWithURL (url);// 2
CFRelease(url);
int count = CGPDFDocumentGetNumberOfPages (document);// 3
if (count == 0)
printf("`%s' needs at least one page!", filename);
return NULL;
return document;
void MyDisplayPDFPage (CGContextRef myContext,size_t pageNumber,const char *filename, CGPDFOperatorTableRef tblRef, NSMutableString *mainStr)
CGPDFDocumentRef document;
CGPDFPageRef page;
document = MyGetPDFDocumentRef (filename);// 1
totalPages=CGPDFDocumentGetNumberOfPages(document);
page = CGPDFDocumentGetPage (document, pageNumber);// 2
CGContextDrawPDFPage (myContext, page);// 3
CGContextTranslateCTM(myContext, 0, 20);
CGContextScaleCTM(myContext, 1.0, -1.0);
CGPDFDocumentRelease (document);// 4
现在,将以下代码放入您的 viewController.m 文件中。
-(void)viewDidLoad
filePath=[[NSString alloc] initWithString:[[NSBundle mainBundle] pathForResource:@"roadie" ofType:@"pdf"]];
CGPDFDocumentRef d=MyGetPDFDocumentRef([filePath UTF8String]);
size_t nos=CGPDFDocumentGetNumberOfPages(d);
totalPages=nos;
arrImgs=[[NSMutableArray alloc] init]; // arrImgs variable declared in viewController.h file.
setRefImgs(arrImgs);
int i;
for(i=0;i<nos;i++)
UIGraphicsBeginImageContext(CGSizeMake(720, 720));
MyDisplayPDFPage(UIGraphicsGetCurrentContext(), i+1, [filePath UTF8String],myTable,mainString);
UIImage *tmp=UIGraphicsGetImageFromCurrentImageContext();
UIImage *t2=[tmp rotate:UIImageOrientationDownMirrored];
[arrPDFImgs addObject:t2];
UIImageView *imgV=[[UIImageView alloc] initWithFrame:CGRectMake(scrPDFImages.frame.size.width * i, 0, scrPDFImages.frame.size.width, scrPDFImages.frame.size.height)];
[imgV setContentMode:UIViewContentModeScaleToFill];
[imgV setImage:t2];
[scrPDFImages addSubview:imgV];
// scrPDFImages is an array that has all images
// per page one image from pdf document
[imgV release];
UIGraphicsPopContext();
您可能需要图像方向 - 我也将整个班级放在这里。
@interface UIImage (WBImage)
// rotate UIImage to any angle
-(UIImage*)rotate:(UIImageOrientation)orient;
@end
@implementation UIImage (WBImage)
static inline CGFloat degreesToRadians(CGFloat degrees)
return M_PI * (degrees / 180.0);
static inline CGSize swapWidthAndHeight(CGSize size)
CGFloat swap = size.width;
size.width = size.height;
size.height = swap;
return size;
-(UIImage*)rotate:(UIImageOrientation)orient
CGRect bnds = CGRectZero;
UIImage* copy = nil;
CGContextRef ctxt = nil;
CGRect rect = CGRectZero;
CGAffineTransform tran = CGAffineTransformIdentity;
bnds.size = self.size;
rect.size = self.size;
switch (orient)
case UIImageOrientationUp:
return self;
case UIImageOrientationUpMirrored:
tran = CGAffineTransformMakeTranslation(rect.size.width, 0.0);
tran = CGAffineTransformScale(tran, -1.0, 1.0);
break;
case UIImageOrientationDown:
tran = CGAffineTransformMakeTranslation(rect.size.width,
rect.size.height);
tran = CGAffineTransformRotate(tran, degreesToRadians(180.0));
break;
case UIImageOrientationDownMirrored:
tran = CGAffineTransformMakeTranslation(0.0, rect.size.height);
tran = CGAffineTransformScale(tran, 1.0, -1.0);
break;
case UIImageOrientationLeft:
bnds.size = swapWidthAndHeight(bnds.size);
tran = CGAffineTransformMakeTranslation(0.0, rect.size.width);
tran = CGAffineTransformRotate(tran, degreesToRadians(-90.0));
break;
case UIImageOrientationLeftMirrored:
bnds.size = swapWidthAndHeight(bnds.size);
tran = CGAffineTransformMakeTranslation(rect.size.height,
rect.size.width);
tran = CGAffineTransformScale(tran, -1.0, 1.0);
tran = CGAffineTransformRotate(tran, degreesToRadians(-90.0));
break;
case UIImageOrientationRight:
bnds.size = swapWidthAndHeight(bnds.size);
tran = CGAffineTransformMakeTranslation(rect.size.height, 0.0);
tran = CGAffineTransformRotate(tran, degreesToRadians(90.0));
break;
case UIImageOrientationRightMirrored:
bnds.size = swapWidthAndHeight(bnds.size);
tran = CGAffineTransformMakeScale(-1.0, 1.0);
tran = CGAffineTransformRotate(tran, degreesToRadians(90.0));
break;
default:
// orientation value supplied is invalid
assert(false);
return nil;
UIGraphicsBeginImageContext(bnds.size);
ctxt = UIGraphicsGetCurrentContext();
switch (orient)
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
CGContextScaleCTM(ctxt, -1.0, 1.0);
CGContextTranslateCTM(ctxt, -rect.size.height, 0.0);
break;
default:
CGContextScaleCTM(ctxt, 1.0, -1.0);
CGContextTranslateCTM(ctxt, 0.0, -rect.size.height);
break;
CGContextConcatCTM(ctxt, tran);
CGContextDrawImage(ctxt, rect, self.CGImage);
copy = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return copy;
@end
【讨论】:
如何控制所创建图像的大小/质量? pdf 页面是基于矢量的,放大后看起来很完美。为了让图像在放大时看起来不错,我需要创建一个更高分辨率的版本。如何做到这一点? 请将它添加到您的问题中 - 您还想要缩放。 我也有缩放的解决方案。但它会在我的答案中添加更多代码。 @Spark: MyDisplayPDFPage(UIGraphicsGetCurrentContext(), i+1, [filePath UTF8String],myTable,mainString) 中的 myTable 是什么;以上是关于将 PDF 加载到屏幕外图层的主要内容,如果未能解决你的问题,请参考以下文章