public
Created

Create iOS image resources from a PDF on the fly.

  • Download Gist
LoadImage.h
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14
//
// LoadImage.h
// AssetsFromPDF
//
// Created by Jeffrey Sambells on 2012-03-02.
//
 
#import <Foundation/Foundation.h>
 
@interface LoadImage : NSObject
 
+ (void)LoadFromPDF:(NSString *)fileNameWithoutExtension size:(CGSize)size callback:(void (^)(UIImage *))callback;
 
@end
LoadImage.m
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
//
// LoadImage.m
// AssetsFromPDF
//
// Created by Jeffrey Sambells on 2012-03-02.
//
 
#import "LoadImage.h"
#import "NSThread+Blocks.h"
 
@implementation LoadImage
 
+ (void)LoadFromPDF:(NSString *)fileNameWithoutExtension size:(CGSize)size callback:(void (^)(UIImage *))callback {
[NSThread performBlockInBackground:^{
 
// 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.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *fileManger = [NSFileManager defaultManager];
// Define the formats for the image names (low and high res).
NSString *path = @"rendered-%@.png";
NSString *pathHigh = @"rendered-%@@2x.png";
// Get the file name.
NSString *file = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:( isRetina ? pathHigh : path ) , fileNameWithoutExtension]];
UIImage *image;
if ( ![fileManger fileExistsAtPath:file] ) {
// Image doesn't exist so load the PDF and create it.
// Get a reference to the PDF.
NSString *pdfName = [NSString stringWithFormat:@"%@.pdf", fileNameWithoutExtension];
CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), (__bridge CFStringRef)pdfName, NULL, NULL);
CGPDFDocumentRef pdfDoc = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
CFRelease(pdfURL);
if (isRetina) {
UIGraphicsBeginImageContextWithOptions(size, false, 0);
} else {
UIGraphicsBeginImageContext( size );
}
// Load the first page. You could have multiple pages if you wanted.
CGPDFPageRef pdfPage = CGPDFDocumentGetPage(pdfDoc, 1);
CGContextRef context = UIGraphicsGetCurrentContext();
// PDF page drawing expects a lower-left coordinate system,
// flip the coordinate system before we start drawing.
CGRect bounds = CGContextGetClipBoundingBox(context);
CGContextTranslateCTM(context, 0, bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// Save the graphics state.
CGContextSaveGState(context);
// CGPDFPageGetDrawingTransform provides an easy way to get the transform
// for a PDF page. It will scale down to fit, including any
// base rotations necessary to display the PDF page correctly.
CGRect transformRect = CGRectMake(0, 0, size.width, size.height);
CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(pdfPage, kCGPDFCropBox, transformRect, 0, true);
// 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.
[UIImagePNGRepresentation(image) writeToFile:file atomically:YES];
UIGraphicsEndImageContext();
CGPDFDocumentRelease(pdfDoc);
} else {
// Load the image from the file system.
image = [UIImage imageWithContentsOfFile:file];
}
[[NSThread mainThread] performBlock:^{
callback(image);
}];
}];}
 
@end
NSThread+Blocks.h
Objective-C
1 2 3 4 5 6 7 8 9 10 11
//
// NSThread+Blocks.h
//
 
#import <Foundation/Foundation.h>
 
@interface NSThread (BlocksAdditions)
- (void)performBlock:(void (^)())block;
- (void)performBlock:(void (^)())block waitUntilDone:(BOOL)wait;
+ (void)performBlockInBackground:(void (^)())block;
@end
NSThread+Blocks.m
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
//
// NSThread+Blocks.m
//
 
#import "NSThread+Blocks.h"
 
@implementation NSThread (BlocksAdditions)
 
- (void)performBlock:(void (^)())block
{
if ([[NSThread currentThread] isEqual:self])
block();
else
[self performBlock:block waitUntilDone:NO];
}
 
- (void)performBlock:(void (^)())block waitUntilDone:(BOOL)wait
{
[NSThread performSelector:@selector(ng_runBlock:)
onThread:self
withObject:[block copy]
waitUntilDone:wait];
}
 
+ (void)ng_runBlockPool:(void (^)())block
{
@autoreleasepool {
block();
}
}
 
+ (void)ng_runBlock:(void (^)())block
{
block();
}
 
+ (void)performBlockInBackground:(void (^)())block
{
[NSThread performSelectorInBackground:@selector(ng_runBlockPool:)
withObject:[block copy]];
}
 
@end
NSThreadBlocks.h
Objective-C
1 2 3 4 5 6 7 8 9 10 11
//
// NSThread+Blocks.h
//
 
#import <Foundation/Foundation.h>
 
@interface NSThread (BlocksAdditions)
- (void)performBlock:(void (^)())block;
- (void)performBlock:(void (^)())block waitUntilDone:(BOOL)wait;
+ (void)performBlockInBackground:(void (^)())block;
@end
NSThreadBlocks.m
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
//
// NSThread+Blocks.m
//
 
#import "NSThread+Blocks.h"
 
@implementation NSThread (BlocksAdditions)
 
- (void)performBlock:(void (^)())block
{
if ([[NSThread currentThread] isEqual:self])
block();
else
[self performBlock:block waitUntilDone:NO];
}
 
- (void)performBlock:(void (^)())block waitUntilDone:(BOOL)wait
{
[NSThread performSelector:@selector(ng_runBlock:)
onThread:self
withObject:[block copy]
waitUntilDone:wait];
}
 
+ (void)ng_runBlockPool:(void (^)())block
{
@autoreleasepool {
block();
}
}
 
+ (void)ng_runBlock:(void (^)())block
{
block();
}
 
+ (void)performBlockInBackground:(void (^)())block
{
[NSThread performSelectorInBackground:@selector(ng_runBlockPool:)
withObject:[block copy]];
}
 
@end
Readme.md
Markdown

Usage Example

Rendering iOS image assets (with retina) dynamically from a PDF.

//
//  ViewController.m
//
//  Created by Jeffrey Sambells on 2012-03-02.
//

#import "ViewController.h"
#import "LoadImage.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.frame];
    [imageView setContentMode:UIViewContentModeCenter];
    [self.view addSubview:imageView];

    [LoadImage LoadFromPDF:@"apple_logo" size:CGSizeMake(100.0f,100.0f) callback:^(UIImage *image){
        [imageView setImage:image];
    }];

}

@end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.