Search code examples
iosxcodepdfpng

PDF Printing Transparent Backgrounds


My app does PDF creation. As part of it, I have successfully allowed the user to add an image, and the image is cropped to a circle and added. When you view the subsequently created PDF on the screen, or on a computer screen, it looks great. But when you print it off, it prints part of that transparent background off, as seen in the images versus how it looks on screen. Is this a problem with PDFKit within Xcode or is there something I can be doing to fix this?

- (void) generatePdfWithFilePath2: (NSString *)thefilePath
{
    UIGraphicsBeginPDFContextToFile(thefilePath, CGRectZero, nil);
    
    BOOL done = NO;
    do
    {
        UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);
        
        [self drawImage];
        [self drawImage2];
        [self drawText];
        [self drawText2];
        [self drawText4];
        [self drawText5];
        
        done = YES;
    }
    while (!done);
    
    // Close the PDF context and write the contents out.
    UIGraphicsEndPDFContext();
    
}

And to draw the image:

- (void) drawImage2
{
    UIImage * demoImage = self.imageCopy;
    NSData *pngData = UIImagePNGRepresentation(demoImage);
    CGDataProviderRef dp = CGDataProviderCreateWithCFData(( CFDataRef)pngData);
    CGImageRef cgImage = CGImageCreateWithPNGDataProvider(dp, NULL, true, kCGRenderingIntentDefault);
    [[UIImage imageWithCGImage:cgImage] drawInRect:CGRectMake(100, 371.82, 190, 190)];

}

enter image description here

enter image description here


Solution

  • Couple things...

    1. Is there a reason you are converting to CGImage and back?
    2. Are you sure the background is completely transparent?
    3. If you're sure, then you may want to try using a clipping path.

    Here's the result of my quick test...

    Using this as the "background" image:

    enter image description here

    and these two images to overlap the background, with transparency - first image has an alpha / transparent area, second image does not:

    enter image description here

    enter image description here

    Using this code:

    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    - (IBAction)didTap:(id)sender {
    
        NSFileManager *fileManager = [NSFileManager defaultManager];
        
        //Get documents directory
        NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains
        (NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectoryPath = [directoryPaths objectAtIndex:0];
        
        NSString *path = [documentsDirectoryPath stringByAppendingPathComponent:@"SomeFileName.pdf"];
        
        [self generatePdfWithFilePath2:path];
        
    }
    
    - (void) generatePdfWithFilePath2: (NSString *)thefilePath
    {
        UIGraphicsBeginPDFContextToFile(thefilePath, CGRectZero, nil);
        
        CGSize pageSize = CGSizeMake(612, 792);
        
        BOOL done = NO;
        do
        {
            UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);
            
            [self drawImage1];
            [self drawImage2];
            [self drawImage3];
            [self drawImage4];
            
            done = YES;
        }
        while (!done);
        
        // Close the PDF context and write the contents out.
        UIGraphicsEndPDFContext();
        
    }
    
    - (void) drawImage1
    {
        UIImage * demoImage = [UIImage imageNamed:@"bkgGradient"];
        [demoImage drawInRect:CGRectMake(50, 50, 200, 200)];
    }
    
    - (void) drawImage2
    {
        UIImage * demoImage = [UIImage imageNamed:@"pro1"];
        [demoImage drawInRect:CGRectMake(150, 150, 200, 200)];
    }
    
    - (void) drawImage3
    {
        UIImage * demoImage = [UIImage imageNamed:@"bkgGradient"];
        [demoImage drawInRect:CGRectMake(50, 400, 200, 200)];
    }
    
    - (void) drawImage4
    {
        UIImage * demoImage = [UIImage imageNamed:@"pro2"];
        CGRect r = CGRectMake(150, 500, 200, 200);
        // create a bezier path defining rounded corners
        UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:r cornerRadius:r.size.height];
        // use this path for clipping in the implicit context
        [path addClip];
        [demoImage drawInRect:r];
    }
    

    Here is how it looks on-screen with preview:

    enter image description here

    and a scan (scaled down) of the full printed page:

    enter image description here

    and non-scaled 300-dpi scan of the printed page:

    enter image description here

    enter image description here

    As you can see, both the alpha area of "pro1" and the clipped area of "pro2" are completely transparent, both on-screen and printed.