20

我在这里尝试将单个 PDF 页面转换为 PNG,并且它运行良好,直到 UIGraphicsGetCurrentContext 突然开始返回 nil。

我试图在这里追溯我的步骤,但我不太确定我知道这发生在什么时候。我的帧不是 0,我认为这可能会产生这个问题,但除此之外,一切“看起来”都是正确的。

这是我的代码的开头。

_pdf = CGPDFDocumentCreateWithURL((__bridge CFURLRef)_pdfFileUrl);
CGPDFPageRef myPageRef = CGPDFDocumentGetPage(_pdf, pageNumber);
CGRect aRect = CGPDFPageGetBoxRect(myPageRef, kCGPDFCropBox);
CGRect bRect = CGRectMake(0, 0, height / (aRect.size.height / aRect.size.width), height);
UIGraphicsBeginImageContext(bRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);

有人知道还有什么可能导致零上下文吗?

4

3 回答 3

50

它不必从“drawRect”中调用。你也可以在“UIGraphicsBeginImageContext(bRect.size);”之后调用它

签入以下行

UIGraphicsBeginImageContext(bRect.size);

如果 bRect.size 不是 0,0

就我而言,这就是下一行返回的上下文为空的原因。

于 2014-03-11T20:29:55.310 回答
31

您是否在 drawRect 方法中调用 UIGraphicsGetCurrentContext() ?据我所知,它只能在drawRect中调用,否则它只会返回nil。

于 2012-09-14T12:43:02.283 回答
2

实际上,在 drawRect 方法中设置 CGContextRef 对象后,它是可以重用的。关键是 - 您需要在从任何地方使用 Context 之前将其推送到堆栈。否则,当前上下文将为 0x0
1。添加

@interface RenderView : UIView {
    CGContextRef visualContext;
    BOOL renderFirst;
}


2. 在您的@implementation 中,在视图出现在屏幕上之前先将 renderFirst 设置为 TRUE,然后:

-(void) drawRect:(CGRect) rect {
  if (renderFirst) {
      visualContext = UIGraphicsGetCurrentContext();
      renderFirst = FALSE;
  }
}


3. 设置上下文后将某事渲染到上下文。

-(void) renderSomethingToRect:(CGRect) rect {
   UIGraphicsPushContext(visualContext);
   // For instance
   UIGraphicsPushContext(visualContext);
   CGContextSetRGBFillColor(visualContext, 1.0, 1.0, 1.0, 1.0);
   CGContextFillRect(visualContext, rect);
}


这是一个与线程案例完全匹配的示例:

- (void) drawImage: (CGImageRef) img inRect: (CGRect) aRect {
    UIGraphicsBeginImageContextWithOptions(aRect.size, NO, 0.0);
    visualContext = UIGraphicsGetCurrentContext();
    CGContextConcatCTM(visualContext, CGAffineTransformMakeTranslation(-aRect.origin.x, -aRect.origin.y));
    CGContextClipToRect(visualContext, aRect);
    CGContextDrawImage(visualContext, aRect, img);
    // this can be used for drawing image on CALayer
    self.layer.contents = (__bridge id) img;
    [CATransaction flush];
    UIGraphicsEndImageContext();
}


并从之前在这篇文章中拍摄的上下文中绘制图像:

-(void) drawImageOnContext: (CGImageRef) someIm onPosition: (CGPoint) aPos {
    UIGraphicsPushContext(visualContext);
    CGContextDrawImage(visualContext, CGRectMake(aPos.x,
                    aPos.y, someIm.size.width,
                    someIm.size.height), someIm.CGImage);
}

在需要上下文来呈现对象之前,不要调用 UIGraphicsPopContext() 函数。
当调用方法完成时,似乎 CGContextRef 正在从图形堆栈的顶部自动删除。
无论如何,这个例子似乎是一种 Hack——不是 Apple 计划和提出的。该解决方案非常不稳定,仅适用于屏幕顶部的一个 UIView 内的直接方法消息调用。在“执行选择”调用的情况下,上下文不会将任何结果呈现到屏幕上。因此,我建议使用 CALayer 作为屏幕目标的渲染,而不是直接使用图形上下文。
希望能帮助到你。

于 2015-12-14T21:01:49.477 回答