将 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 加载到屏幕外图层的主要内容,如果未能解决你的问题,请参考以下文章

CAGradientLayer 未应用于整个屏幕

iOS动画原理--模型树和呈现树

OpenLayers创建一个新的Vector图层并添加覆盖物,并监听图层事件

将加载屏幕添加到 iphone 应用程序

OpenGL 加载和渲染 png 到屏幕

解释:为啥有人需要将 img 1x1 像素加载到屏幕外?