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);

誰かが他に何がnilコンテキストを引き起こしているのか考えていますか?

4

3 に答える 3

50

「drawRect」から呼び出す必要はありません。「UIGraphicsBeginImageContext(bRect.size);」の後に呼び出すこともできます。

次の行でチェックイン

UIGraphicsBeginImageContext(bRect.size);

bRect.size が 0,0 でない場合

私の場合、これが次の行で返されたコンテキストが null だった理由です。

于 2014-03-11T20:29:55.310 に答える
31

drawRect メソッド内で UIGraphicsGetCurrentContext() を呼び出していますか? 私の知る限り、drawRect 内でのみ呼び出すことができます。それ以外の場合は、単に nil を返します。

于 2012-09-14T12:43:02.283 に答える
2

Indeed, it is possible to have CGContextRef object reusable after it has been set in drawRect method. The point is - you need to push the Context to the stack before using it from anywhere. Otherwise, current context will be 0x0
1. Add

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


2. In your @implementation first set renderFirst to TRUE before view has appeared on the screen, then:

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


3. Rendering Something to the context after the context was set.

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


Here is an example exactly matching the thread case:

- (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();
}


And Drawing image from context that was taken before in this post:

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

Do not call UIGraphicsPopContext() function until you need the context to render your objects.
It seems that CGContextRef is being removed from the top of the graphic stack automatically when the calling method finishes.
Anyway, this example seems to be a kind of Hack - not planned and proposed by Apple. The solution is very unstable and works only with direct method messages calls inside only one UIView that is on the top of the screen. In case of "performselection" calls, Context does not render any results to the screen. So, I suggest to use CALayer as a rendering to the screen target instead of direct graphic context usage.
Hope it helps.

于 2015-12-14T21:01:49.477 に答える