Vectorial PDF graphic elements on iOS
Currently implementing vectorial interface elements on iOS is very peculiar, UIImage advertises support only for raster formats but i am able to set a pdf file as the image of a UIButton in IB
searchButton = [UIButton buttonWithType:UIButtonTypeCustom];
[searchButton setImage:[UIImage imageNamed:@"search"] forState:UIControlStateNormal];
[self.view addSubview:searchButton];
However this only shows the image on iOS 4.x and with considerable resize pixelation and no antialiasing as illustrated:
Besides the obvious questions of why it looks this bad, why it only works in 4.x, and why the IB version does not work at all, does anyone know any ways to properly user vectorial art in apps?
It does not have to be necessarily PDF but I have seen Apple use that a lot on the mac side apps, both th开发者_Python百科e code and IB approaches above work perfectly on OSX apps BTW.
As iOS misses the PDFKit.framework i guess that the issue with the limited/broken PDF support of UIImage is that it is not supposed to have any support in the first place, in that respect i have reported the limited support it has as a bug (rdar:8338627) and it is a bug in IB too with the rendering support being probably carried over from osx.
I have settled to just rendering the pdf manually in a context then saving that to a UIImage, the code for which is below (tested on iOS 3.x and 4.x)
#include <dlfcn.h>
-(UIImage *)UIImageFromPDF:(NSString*)fileName size:(CGSize)size{
CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), (CFStringRef)fileName, NULL, NULL);
if (pdfURL) {
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL(pdfURL);
CFRelease(pdfURL);
//create context with scaling 0.0 as to get the main screen's if iOS4+
if (dlsym(RTLD_DEFAULT,"UIGraphicsBeginImageContextWithOptions") == NULL) {
UIGraphicsBeginImageContext(size);
}else {
UIGraphicsBeginImageContextWithOptions(size,NO,0.0);
}
CGContextRef context = UIGraphicsGetCurrentContext();
//translate the content
CGContextTranslateCTM(context, 0.0, size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSaveGState(context);
//scale to our desired size
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, CGRectMake(0, 0, size.width, size.height), 0, true);
CGContextConcatCTM(context, pdfTransform);
CGContextDrawPDFPage(context, page);
CGContextRestoreGState(context);
//return autoreleased UIImage
UIImage *ret = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGPDFDocumentRelease(pdf);
return ret;
}else {
NSLog(@"Could not load %@",fileName);
}
return nil;
}
There's a great project that helps with rendering PDF into UIImages.
https://github.com/mindbrix/UIImage-PDF
I don't know why UIImage doesn't work well with PDF, but it should be possible to write your own code to draw a PDF. See the "Opening and Viewing a PDF" section in the Quartz 2D Programming Guide. You could draw the PDF into a CGBitmapContext, use that to create a CGImage, and use that to create a UIImage.
精彩评论