Подтвердить что ты не робот

UIGraphicsGetCurrentContext, похоже, возвращает ноль

Я пытаюсь преобразовать отдельные PDF-страницы в PNG здесь, и он отлично работал, пока UIGraphicsGetCurrentContext внезапно не начал возвращать нуль.

Я пытаюсь восстановить свои шаги здесь, но я не совсем уверен, что знаю, в какой момент это произошло. Мой кадр не равен 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?

4b9b3361

Ответ 1

В самом деле, возможно, что объект CGContextRef можно повторно использовать после того, как он был установлен в методе drawRect. Дело в том, что перед тем, как использовать его из любого места, вам нужно нажать контекст в стек. В противном случае текущий контекст будет 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 автоматически удаляется из верхней части графического стека, когда заканчивается метод вызова.
Во всяком случае, этот пример кажется своего рода хаком - не запланированным и предложенным Apple. Решение очень неустойчиво и работает только с прямыми вызовами сообщений метода внутри только одного UIView, который находится в верхней части экрана. В случае вызовов "performselection" Context не дает никаких результатов на экране. Поэтому я предлагаю использовать CALayer как рендеринг для целевой страницы экрана вместо прямого использования графического контекста.
Надеюсь, что это поможет.

Ответ 2

Его не нужно вызывать из "drawRect". вы также можете вызвать его после "UIGraphicsBeginImageContext (bRect.size)";

Проверьте следующую строку

UIGraphicsBeginImageContext(bRect.size);

если bRect.size не 0,0

В моем случае это послужило причиной того, что возвращаемый контекст в следующей строке был нулевым.

Ответ 3

Вы вызываете UIGraphicsGetCurrentContext() внутри метода drawRect? Насколько мне известно, его можно вызвать только в drawRect, иначе он просто вернет нуль.