Last active
September 23, 2021 15:49
-
-
Save balazsnemeth/b9cf6cdbaa3e9d624598 to your computer and use it in GitHub Desktop.
PDF to UIImage fitting a given size with file cache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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