2010-10-11 11 views
7

Je consultant une page pdf sur le CGContext en utilisant le codeCGContext aspect page pdf correspondent

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

Le problème est que la page de pdf est de se tirer sur le centre de la page en laissant la frontière sur les quatre côtés. Y a-t-il un moyen de rendre la page adaptée à l'écran?

Répondre

15

Pour développer la réponse de Tia; la méthode intégrée CGPDFPageGetDrawingTransform sera réduite mais pas mise à jour. Si vous voulez faire évoluer votre système, vous devez élaborer votre propre transformation en comparant les résultats de CGPDFGetBoxRect à votre zone de contenu. Taper extemporanée:

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

donc: savoir combien vous auriez à l'échelle du document par pour elle d'occuper toute la largeur de la vue, combien d'occuper toute la hauteur et l'échelle fait par le moindre de ces deux valeurs.

+0

pouvez-vous s'il vous plaît répondre à cette question, je suis aussi essayer de la même manière, mais je ne peux pas obtenir la forme exacte http://stackoverflow.com/questions/3908624/cgcontext-pdf-page-aspect-fit – ajay

+0

C'est un lien vers cette question; probablement vous vouliez dire http://stackoverflow.com/questions/4321681/how-to-fit-pdf-page-in-entire-view? Je vais jeter un coup d'oeil dès que j'en aurai l'opportunité, même si je suis malheureusement sur le point de sortir maintenant ... – Tommy

+0

Mise à jour mineure, CGPDFGetBoxRect semble être maintenant CGPDFPageGetBoxRect mais incroyablement utile! Cette taille m'a rendu fou. Vous pouvez également trouver la ligne CGContextConcatCTM (ctx, CGPDFPageGetDrawingTransform (myPageRef, kCGPDFCropBox, layer.bounds, 0, true)); avant que le fichier CGContextDrawPDFPage ne soit pris en charge avec les fichiers PDF faisant l'objet de 90 conversions – sradforth

1

La lecture cursive de votre code suggère que l'utilisation de kCGPDFBleedBox soit remplacée par un autre paramètre, peut-être kCGPDFMediaBox. Voir here pour plus d'informations.

+0

fbrereto, j'ai essayé kCGPDFMediaBox et toutes les autres options disponibles. Mais il n'y a pas de changement dans l'affichage. –

2

Le CGPDFPageGetDrawingTransform ne retournera tout simplement pas la transformation de mise à l'échelle si le rectangle de la page PDF est plus petit que le paramètre rect.

+0

tia, j'ai essayé la même page dans d'autres applications de lecture de pdf et est affichée correctement adaptée à l'écran. Donc, y a-t-il un autre moyen de le dessiner pour qu'il soit en forme? –

0

Les autres réponses sont correctes: CGPDFPageGetDrawingTransform n'augmentera pas, mais vous pouvez redimensionner le rectangle pour capturer uniquement la zone choisie. Utilisez CGPDFPageGetBoxRect() et calculez l'échelle comme suggéré par Tommy dans la réponse acceptée, puis utilisez-la pour réduire le rectangle de capture transmis dans 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); 
} 

Ensuite, il est facilement étendu pour gérer le paysage aussi:

- (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

Voici ma solution, qui gère également la rotation. Pourrait utile.

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