上下文绘图 +分页

发布于 2024-12-07 11:50:09 字数 1705 浏览 0 评论 0原文

我正在尝试将 scrollview 的内容绘制到 PDF 上下文中我面临分页问题。

我使用了以下代码:

- (void)renderTheView:(UIView *)view inPDFContext:(CGContextRef)pdfContext
{
    // Creating frame.
    CGFloat heightOfPdf = [[[self attributes] objectForKey:SRCPdfHeight] floatValue];
    CGFloat widthOfPdf  = [[[self attributes] objectForKey:SRCPdfWidth] floatValue];
    CGRect pdfFrame = CGRectMake(0, 0, widthOfPdf, heightOfPdf);   
    CGRect viewFrame = [view frame];

    if ([view isKindOfClass:[UIScrollView class]])
    {
        viewFrame.size.height = ((UIScrollView *)view).contentSize.height;
        [view setFrame:viewFrame];
    }
    // Calculates number of pages.
    NSUInteger totalNumberOfPages = ceil(viewFrame.size.height/heightOfPdf);

    // Start rendering.
    for (NSUInteger pageNumber = 0; pageNumber<totalNumberOfPages; pageNumber++)
    {
       // Starts our first page.
       CGContextBeginPage (pdfContext, &pdfFrame);  
       // Turn PDF upsidedown
       CGAffineTransform transform = CGAffineTransformIdentity;
       transform = CGAffineTransformMakeTranslation(0,view.bounds.size.height);
       transform = CGAffineTransformScale(transform, 1.0, -1.0);
       CGContextConcatCTM(pdfContext, transform);

       // Calculate amount of y to be displace.
       CGFloat ty = (heightOfPdf*(pageNumber));

       CGContextTranslateCTM(pdfContext,0,-ty);
       [view.layer renderInContext:pdfContext];

       // We are done drawing to this page, let's end it.
       CGContextEndPage (pdfContext);
   }    
}

它创建了所需数量的页面,但内容放置错误。下图解释了它。 在此处输入图像描述

我的代码有什么问题吗?

I am trying to draw contents of scrollview into a PDF context & I am facing problem with pagination.

Following Code I have used:

- (void)renderTheView:(UIView *)view inPDFContext:(CGContextRef)pdfContext
{
    // Creating frame.
    CGFloat heightOfPdf = [[[self attributes] objectForKey:SRCPdfHeight] floatValue];
    CGFloat widthOfPdf  = [[[self attributes] objectForKey:SRCPdfWidth] floatValue];
    CGRect pdfFrame = CGRectMake(0, 0, widthOfPdf, heightOfPdf);   
    CGRect viewFrame = [view frame];

    if ([view isKindOfClass:[UIScrollView class]])
    {
        viewFrame.size.height = ((UIScrollView *)view).contentSize.height;
        [view setFrame:viewFrame];
    }
    // Calculates number of pages.
    NSUInteger totalNumberOfPages = ceil(viewFrame.size.height/heightOfPdf);

    // Start rendering.
    for (NSUInteger pageNumber = 0; pageNumber<totalNumberOfPages; pageNumber++)
    {
       // Starts our first page.
       CGContextBeginPage (pdfContext, &pdfFrame);  
       // Turn PDF upsidedown
       CGAffineTransform transform = CGAffineTransformIdentity;
       transform = CGAffineTransformMakeTranslation(0,view.bounds.size.height);
       transform = CGAffineTransformScale(transform, 1.0, -1.0);
       CGContextConcatCTM(pdfContext, transform);

       // Calculate amount of y to be displace.
       CGFloat ty = (heightOfPdf*(pageNumber));

       CGContextTranslateCTM(pdfContext,0,-ty);
       [view.layer renderInContext:pdfContext];

       // We are done drawing to this page, let's end it.
       CGContextEndPage (pdfContext);
   }    
}

It creates required number of pages but places the content wrongly. Following figure explains it.enter image description here

Is there anything wrong in my code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

妄想挽回 2024-12-14 11:50:09

我认为您不需要将 PDF 翻转的代码。我之前已经这样做过(手动分页,但没有滚动视图)并且从未需要垂直翻转上下文。我主要担心的是,您在每次迭代中都执行此操作 - 如果您有充分的理由翻转它,则您可能不需要在循环中使用它,而只需在循环开始之前执行一次。此外,代码 CGContextTranslateCTM(pdfContext,0,-ty); 可能需要替换为 CGContextTranslateCTM(pdfContext,0,heightOfPdf);

如果这不起作用,请尝试UIGraphicsBeginPDFPage(); 而不是 CGContextBeginPage(),这是你的代码和我的代码之间唯一的主要区别。

I don't think you need the code which flips the PDF upside down. I've done this before (manual pagination, but without a scroll view) and never had to flip the context vertically. My main concern is that you are doing it on every iteration - if you have a valid reason for flipping it, you probably don't need it in the loop, but just once before the loop begins. Also the code CGContextTranslateCTM(pdfContext,0,-ty); might need to be replaced with CGContextTranslateCTM(pdfContext,0,heightOfPdf);

If that doesn't work, try UIGraphicsBeginPDFPage(); instead of CGContextBeginPage(), that's the only major difference between your code and mine.

我只土不豪 2024-12-14 11:50:09

这个 github 项目绝对可以帮助你。

- (void) renderPageAtIndex:(NSUInteger)index inContext:(CGContextRef)ctx {
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, index + 1);
CGAffineTransform transform = aspectFit(CGPDFPageGetBoxRect(page, kCGPDFMediaBox),
                                        CGContextGetClipBoundingBox(ctx));
CGContextConcatCTM(ctx, transform);
CGContextDrawPDFPage(ctx, page);

}

This github project can definitely help you.

- (void) renderPageAtIndex:(NSUInteger)index inContext:(CGContextRef)ctx {
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, index + 1);
CGAffineTransform transform = aspectFit(CGPDFPageGetBoxRect(page, kCGPDFMediaBox),
                                        CGContextGetClipBoundingBox(ctx));
CGContextConcatCTM(ctx, transform);
CGContextDrawPDFPage(ctx, page);

}

冬天的雪花 2024-12-14 11:50:09

找到了这个链接来渲染 PDF,它提到了多个页面,但没有显示实现。它并没有立即回答你的问题,但它告诉了一种更简单的方法来渲染 pdf,并且需要更少的翻译和转换。

渲染 PDF

生成多页 PDF
-阿努普

Found this link to render a PDF, it says about multiple pages but haven't shown an implementation. It doesnt straight away answer to your question but it tells a simpler method to render a pdf with much less translation and transforms.

Render PDF

Generate Multipage PDF
-anoop

虚拟世界 2024-12-14 11:50:09

您可以考虑使用 UIScrollView 来布局单独的 PDF 页面。以下方法加载视图 (PDFView) 中的每个 PDF 页面,并将其以居中方式添加到滚动视图内容中:

- (void) loadPDFAtPath:(NSString *)path
{
    NSURL *pdfUrl = [NSURL fileURLWithPath:path];
    CGPDFDocumentRef document = CGPDFDocumentCreateWithURL((__bridge CFURLRef)pdfUrl);

    float height = 0.0;

    for(int i = 0; i < CGPDFDocumentGetNumberOfPages(document); i++) {
        CGPDFPageRef page = CGPDFDocumentGetPage(document, i + 1);
        PDFView *pdfView = [[PDFView alloc] initPdfViewWithPageRef:page];

        CGRect pageSize = CGPDFPageGetBoxRect(page, kCGPDFCropBox);
        pv.frame = CGRectMake((self.frame.size.width / 2.0) - pageSize.size.width / 2.0, height, pageSize.size.width, pageSize.size.height);
        height += pageSize.size.height + SOME_SPACE_IN_BETWEEN_PAGES;

        // self is a subclass of UIScrollView
        [self addSubview:pdfView];
        [pdfView setNeedsDisplay];
    }

    CGPDFDocumentRelease(document);
    [self setContentSize:CGSizeMake(self.frame.size.width, height)];
}

在本例中,PDFView 负责渲染其drawRect或drawLayer实现中的单个CGPDFPageRef

You could consider using a UIScrollView to layout your separate PDF pages. The following method loads each PDF page in a view (PDFView) and adds it to the scroll view content in a centered fashion:

- (void) loadPDFAtPath:(NSString *)path
{
    NSURL *pdfUrl = [NSURL fileURLWithPath:path];
    CGPDFDocumentRef document = CGPDFDocumentCreateWithURL((__bridge CFURLRef)pdfUrl);

    float height = 0.0;

    for(int i = 0; i < CGPDFDocumentGetNumberOfPages(document); i++) {
        CGPDFPageRef page = CGPDFDocumentGetPage(document, i + 1);
        PDFView *pdfView = [[PDFView alloc] initPdfViewWithPageRef:page];

        CGRect pageSize = CGPDFPageGetBoxRect(page, kCGPDFCropBox);
        pv.frame = CGRectMake((self.frame.size.width / 2.0) - pageSize.size.width / 2.0, height, pageSize.size.width, pageSize.size.height);
        height += pageSize.size.height + SOME_SPACE_IN_BETWEEN_PAGES;

        // self is a subclass of UIScrollView
        [self addSubview:pdfView];
        [pdfView setNeedsDisplay];
    }

    CGPDFDocumentRelease(document);
    [self setContentSize:CGSizeMake(self.frame.size.width, height)];
}

In this case, PDFView is responsible for rendering a single CGPDFPageRef in its drawRect or drawLayer implementation.

吻泪 2024-12-14 11:50:09

您需要添加到 pdf 页面的部分放入滚动内的单独视图中,并将该视图渲染到 pdf 上下文

,或者

只需找到正确的尺寸并使用 CG 方法进行绘制:

        UIImage *Logo=[UIImage imageNamed:@"small-logo-left-top130_133.png"];
    CGPoint drawingLogoOrgin = CGPointMake(5,5);

    UIGraphicsBeginPDFContextToData(pdfData, CGRectZero, nil);
    UIGraphicsBeginPDFPageWithInfo(pageFrame, nil);
    CGContextRef pdfContext = UIGraphicsGetCurrentContext();
    [Logo drawAtPoint:drawingLogoOrgin];

有很多绘制 pdf 的绘制方法。您可以使用它来绘制所有内容。

The portions you need to add to pdf pages put in seperate views inside the scroll and render tht view to the pdf context

OR

Just find the correct dimensions and draw using the CG method:

        UIImage *Logo=[UIImage imageNamed:@"small-logo-left-top130_133.png"];
    CGPoint drawingLogoOrgin = CGPointMake(5,5);

    UIGraphicsBeginPDFContextToData(pdfData, CGRectZero, nil);
    UIGraphicsBeginPDFPageWithInfo(pageFrame, nil);
    CGContextRef pdfContext = UIGraphicsGetCurrentContext();
    [Logo drawAtPoint:drawingLogoOrgin];

There are a lot of drawing methods to draw pdf. You can use that to draw all the contents.

碍人泪离人颜 2024-12-14 11:50:09

这可能对你有帮助。

- (void) renderPageAtIndex:(NSUInteger)index inContext:(CGContextRef)ctx 
{
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, index + 1);
CGAffineTransform transform = aspectFit(CGPDFPageGetBoxRect(page, kCGPDFMediaBox),
                                    CGContextGetClipBoundingBox(ctx));
CGContextConcatCTM(ctx, transform);
CGContextDrawPDFPage(ctx, page);
} 

this might help you.

- (void) renderPageAtIndex:(NSUInteger)index inContext:(CGContextRef)ctx 
{
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, index + 1);
CGAffineTransform transform = aspectFit(CGPDFPageGetBoxRect(page, kCGPDFMediaBox),
                                    CGContextGetClipBoundingBox(ctx));
CGContextConcatCTM(ctx, transform);
CGContextDrawPDFPage(ctx, page);
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文