Skip to content

Instantly share code, notes, and snippets.

@balazsnemeth
Last active September 23, 2021 15:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save balazsnemeth/b9cf6cdbaa3e9d624598 to your computer and use it in GitHub Desktop.
Save balazsnemeth/b9cf6cdbaa3e9d624598 to your computer and use it in GitHub Desktop.
PDF to UIImage fitting a given size with file cache
//based on the solution of iamamused : https://gist.github.com/iamamused/1955318
@implementation UIImage (ImageFromPDF)
+ (UIImage *)imageLoadedFromPDF:(NSString *)filePath fitSize:(CGSize)fitSize shouldCacheAsAFile:(BOOL)storeInFile{
// Determine if the device is retina.
BOOL isRetina = [UIScreen instancesRespondToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2.0;
// Create a file manager so we can check if the image exists and store the image.
NSFileManager *fileManger = [NSFileManager defaultManager];
// Define the formats for the image names (low and high res).
NSString *path = @"%@.png";
NSString *pathHigh = @"%@@2x.png";
//Remove the extension of the input path
NSString * filePathWithoutExtension = [filePath stringByDeletingPathExtension];
// Get the file name.
NSString *file = [NSString stringWithFormat:( isRetina ? pathHigh : path ) , filePathWithoutExtension];
UIImage *image;
if ( ![fileManger fileExistsAtPath:file] ) {
// Image doesn't exist so load the PDF and create it.
// Get a reference to the PDF.
CFURLRef pdfURL = (__bridge CFURLRef)[NSURL fileURLWithPath:filePath];
CGPDFDocumentRef pdfDoc = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
// Load the first page. You could have multiple pages if you wanted.
CGPDFPageRef pdfPage = CGPDFDocumentGetPage(pdfDoc, 1);
//get the Crop Box of the pdf -> could be a various size
CGRect cropBox = CGPDFPageGetBoxRect(pdfPage, kCGPDFCropBox);
//fit the PDF to the given size!
CGFloat xScale = fitSize.width / cropBox.size.width;
CGFloat yScale = fitSize.height / cropBox.size.height;
CGFloat scaleToApply = xScale < yScale ? xScale : yScale;
CGSize size = CGSizeMake(cropBox.size.width*scaleToApply, cropBox.size.height*scaleToApply);
if (isRetina) {
UIGraphicsBeginImageContextWithOptions(size, false, 0);
} else {
UIGraphicsBeginImageContext( size );
}
CGContextRef context = UIGraphicsGetCurrentContext();
// PDF page drawing expects a lower-left coordinate system,
// flip the coordinate system before we start drawing.
CGRect bounds = CGContextGetClipBoundingBox(context);
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
CGContextFillRect(context, bounds);
CGContextTranslateCTM(context, 0, bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// Save the graphics state.
CGContextSaveGState(context);
//high resolution scale -> if the PDF contains vector graphics info
CGAffineTransform pdfTransform = CGAffineTransformMakeScale(scaleToApply, scaleToApply);
// And apply the transform.
CGContextConcatCTM(context, pdfTransform);
// Draw the page.
CGContextDrawPDFPage(context, pdfPage);
// Restore the graphics state.
CGContextRestoreGState(context);
// Generate the image.
image = UIGraphicsGetImageFromCurrentImageContext();
// Store the PNG for next time.
if (storeInFile) {
[UIImagePNGRepresentation(image) writeToFile:file atomically:YES];
NSLog(@"Saved file to pdf: %@",file);
}
UIGraphicsEndImageContext();
CGPDFDocumentRelease(pdfDoc);
} else {
// Load the image from the file system.
image = [UIImage imageWithContentsOfFile:file];
}
return image;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment