2010-10-11 10 views
7

estoy mostrando una página PDF en la CGContext utilizando el códigoCGContext página pdf aspecto encaja

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context 
{ 
    CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0); 
    CGContextFillRect(ctx, layer.bounds); 
    CGContextTranslateCTM(ctx, 0.0, layer.bounds.size.height); 
    CGContextScaleCTM(ctx, 1.0, -1.0); 
    CGContextConcatCTM(ctx, CGPDFPageGetDrawingTransform(myPageRef, kCGPDFBleedBox, layer.bounds, 0, true)); 
    CGContextDrawPDFPage(ctx, myPageRef); 
} 

El problema es que la página PDF se está dibujado en el centro de la página que sale de la frontera en los cuatro lados. ¿Hay alguna manera de hacer que la página se ajuste a la pantalla?

Respuesta

15

Para ampliar la respuesta de Tia; el método integrado CGPDFPageGetDrawingTransform se reducirá pero no hacia arriba. Si desea ampliar su escala, debe calcular su propia transformación comparando los resultados de CGPDFGetBoxRect con su área de contenido. Al escribir de manera extemporánea:

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context 
{ 
    CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0); 
    CGContextFillRect(ctx, layer.bounds); 
    CGContextTranslateCTM(ctx, 0.0, layer.bounds.size.height); 
    CGContextScaleCTM(ctx, 1.0, -1.0); 

    CGRect cropBox = CGPDFGetBoxRect(myPageRef, kCGPDFCropBox); 
    CGRect targetRect = layer.bounds; 
    CGFloat xScale = targetRect.size.width/cropBox.size.width; 
    CGFloat yScale = targetRect.size.height/cropBox.size.height; 
    CGFloat scaleToApply = xScale < yScale ? xScale : yScale; 
    CGContextConcatCTM(ctx, CGAffineTransformMakeScale(scaleToApply, scaleToApply));  

    CGContextDrawPDFPage(ctx, myPageRef); 
} 

Así: calcular cuánto tendría que escalar el documento para que ocupe todo el ancho de la vista, lo mucho que ocupan toda la altura y luego en realidad escalar por el menor de esos dos valores

+0

puede por favor responder esta pregunta, yo también estoy tratando de la misma manera, pero no puedo obtener el ajuste exacto http://stackoverflow.com/questions/3908624/cgcontext-pdf-page-aspect-fit – ajay

+0

Ese es un enlace a esta pregunta; ¿probablemente se refería a http://stackoverflow.com/questions/4321681/how-to-fit-pdf-page-in-entire-view? Echaré un vistazo tan pronto como tenga la oportunidad, aunque estoy tristemente en camino de salir ahora ... – Tommy

+0

Actualización menor, CGPDFGetBoxRect parece ser ahora CGPDFPageGetBoxRect pero increíblemente útil. Este tamaño me ha estado volviendo loco. También puede encontrar incluyendo la línea CGContextConcatCTM (ctx, CGPDFPageGetDrawingTransform (myPageRef, kCGPDFCropBox, layer.bounds, 0, true)); antes de CGContextDrawPDFPage ayuda con cualquier PDF que se rotan 90 degees – sradforth

1

La lectura provisional de su código sugiere que el uso de kCGPDFBleedBox debe ser reemplazado por otra configuración, quizás kCGPDFMediaBox. Consulte here para obtener más información.

+0

fbrereto, probé kCGPDFMediaBox y todas las demás opciones disponibles. Pero no hay cambio en la pantalla. –

2

El CGPDFPageGetDrawingTransform simplemente no devolverá la transformación de escala si el rectángulo de la página PDF es más pequeño que el parámetro rect.

+0

tia, probé la misma página en algunas otras aplicaciones de lector de PDF y se muestra correctamente ajustado a la pantalla. Entonces, ¿hay alguna otra forma de dibujarlo para que se ajuste a un aspecto? –

0

Las otras respuestas son correctas de que CGPDFPageGetDrawingTransform no se ampliará, sin embargo, puede escalar el rectángulo para capturar solo el cuadro elegido. Use CGPDFPageGetBoxRect() y calcule la escala tal como sugirió Tommy en la respuesta aceptada, luego use eso para escalar el rectángulo de captura pasado a CGPDFPageGetDrawingTransform().

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context 
{ 
    CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0); 
    CGContextFillRect(ctx, layer.bounds); 
    CGContextTranslateCTM(ctx, 0.0, layer.bounds.size.height); 

    CGRect box = CGPDFGetBoxRect(myPageRef, kCGPDFBleedBox); 
    CGFloat xScale = layer.bounds.size.width/cropBox.size.width; 
    CGFloat yScale = layer.bounds.size.height/cropBox.size.height; 
    CGFloat scaleToApply = xScale < yScale ? xScale : yScale; 

    CGRect captureRect = CGRectMake(0, 0, 
            layer.bounds.size.width/scaleToApply, 
            layer.bounds.size.height/scaleToApply); 

    CGAffineTransform drawXfm = CGPDFPageGetDrawingTransform(myPageRef, 
                  kCGPDFBleedBox, 
                  captureRect, 
                  0, 
                  true); 

    CGContextScaleCTM(ctx, scaleToApply, -scaleToApply); 
    CGContextConcatCTM(ctx, drawXfm); 
    CGContextDrawPDFPage(ctx, myPageRef); 
} 

entonces es fácilmente extendido para manejar paisaje también:

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context 
{ 
    CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0); 
    CGContextFillRect(ctx, layer.bounds); 
    CGContextTranslateCTM(ctx, 0.0, layer.bounds.size.height); 

    CGRect box = CGPDFGetBoxRect(myPageRef, kCGPDFBleedBox); 
    int rotate; 
    CGFloat xScale, yScale; 
    if (box.size.width > box.size.height) { 
     // landscape 
     rotate = 270; 
     xScale = layer.bounds.size.height/cropBox.size.width; 
     yScale = layer.bounds.size.width/cropBox.size.height; 
    } else { 
     // portrait 
     rotate = 0; 
     xScale = layer.bounds.size.width/cropBox.size.width; 
     yScale = layer.bounds.size.height/cropBox.size.height; 
    } 
    CGFloat scaleToApply = xScale < yScale ? xScale : yScale; 

    CGRect captureRect = CGRectMake(0, 0, 
            layer.bounds.size.width/scaleToApply, 
            layer.bounds.size.height/scaleToApply); 

    CGAffineTransform drawXfm = CGPDFPageGetDrawingTransform(myPageRef, 
               kCGPDFBleedBox, 
               captureRect, 
               rotate, 
               true); 

    CGContextScaleCTM(ctx, scaleToApply, -scaleToApply); 
    CGContextConcatCTM(ctx, drawXfm); 
    CGContextDrawPDFPage(ctx, myPageRef); 
} 
0

Aquí está mi solución, que también se encarga de rotación. Podría por útil.

// Create transformation 
int rotation = CGPDFPageGetRotationAngle(pdfPage); 
CGRect rect = CGPDFPageGetBoxRect(pdfPage, kCGPDFCropBox); 
CGRect rotatedRect = rect; 
CGRectApplyAffineTransform(rotatedRect, CGAffineTransformMakeRotation(M_PI * rotation/180.0)); 

CGFloat scale = MIN(self.bounds.size.width/rotatedRect.size.width, self.bounds.size.height/rotatedRect.size.height); 
// Scale 
CGContextConcatCTM(context, CGAffineTransformMakeScale(scale, scale)); 
// Move left bottom cornet to 0, 0 
CGContextConcatCTM(context, CGAffineTransformMakeTranslation(rotatedRect.size.width * 0.5, rotatedRect.size.height * 0.5));  
// Rotate 
CGContextConcatCTM(context, CGAffineTransformMakeRotation(-M_PI * rotation/180.0));  
// Move center into 0, 0 
CGContextConcatCTM(context, CGAffineTransformMakeTranslation(-rect.origin.x - rect.size.width * 0.5, -rect.origin.y - rect.size.height * 0.5)); 

CGContextDrawPDFPage(context, pdfPage);