Search code examples
iphoneobjective-ciospdfretina-display

Retina PDF Image Rendering for iOS


I have the following code which renders a PDF with an image in the centre of the page. However, the image (and also the text actually) looks very pixelated and is clearly not designed for retina displays.

What am I not doing in the following code?

-(void)drawText
{
    NSString* fileName = @"Workbook.PDF";

    NSArray *arrayPaths =
    NSSearchPathForDirectoriesInDomains(
                                    NSDocumentDirectory,
                                    NSUserDomainMask,
                                    YES);
    NSString *path = [arrayPaths objectAtIndex:0];
    NSString* pdfFileName = [path stringByAppendingPathComponent:fileName];

    // Create the PDF context using the default page size of 612 x 792.
    UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil);
    CGContextSetShouldAntialias(UIGraphicsGetCurrentContext(), YES);

    for(UIImage *image in _pages)
    {

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    NSString* textToDraw = [NSString stringWithFormat:@"Page %i of %@", [_pages indexOfObject:image] + 1, [defaults objectForKey:@"OpenBookKey"]];
    CFStringRef stringRef = (__bridge CFStringRef)textToDraw;

    // Prepare the text using a Core Text Framesetter.
    CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, stringRef, NULL);
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);

    CGRect frameRect = CGRectMake(230, 0, 612, 50);
    CGMutablePathRef framePath = CGPathCreateMutable();
    CGPathAddRect(framePath, NULL, frameRect);

    // Get the frame that will do the rendering.
    CFRange currentRange = CFRangeMake(0, 0);
    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, NULL);
    CGPathRelease(framePath);

    // Mark the beginning of a new page.
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);

    // Get the graphics context.
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    CGRect frame = CGRectMake(20, 50, 550, 550);
    [image drawInRect:frame];

    CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);

    CGContextTranslateCTM(currentContext, 0, 100);
    CGContextScaleCTM(currentContext, 1.0, -1.0);

    // Draw the frame.
    CTFrameDraw(frameRef, currentContext);

    CFRelease(frameRef);
    CFRelease(stringRef);
    CFRelease(framesetter);

    }

    // Close the PDF context and write the contents out.
    UIGraphicsEndPDFContext();

}

Solution

  • There is nothing to do with Retina display, all you need is resize image with aspect fit to reduce pixellating. You can refer my code, You will need to add code to manage your image size, for resizing it

    UIGraphicsBeginPDFContextToFile(pdfPath, CGRectZero, nil);
    for (UIImage *img in FileArr ) {
        CGRect imageFrame = CGRectMake(0,0, img.size.width, img.size.height);
        UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, img.size.width, img.size.height), nil);
        [img drawInRect:imageFrame];
        NSString *pageString = [NSString stringWithFormat:@"Page 122"];
        UIFont *theFont = [UIFont systemFontOfSize:12];
        CGSize maxSize = CGSizeMake(612, 72);
        CGSize pageStringSize = [pageString sizeWithFont:theFont
                                       constrainedToSize:maxSize
                                           lineBreakMode:UILineBreakModeClip];
        CGRect stringRect = CGRectMake(((612.0 - pageStringSize.width) / 2.0),
                                       720.0 + ((72.0 - pageStringSize.height) / 2.0),
                                       pageStringSize.width,
                                       pageStringSize.height);
        [pageString drawInRect:stringRect withFont:theFont];
    }
    UIGraphicsEndPDFContext();