大多數(shù)情況下, 通常直接使用標(biāo)準(zhǔn)的view來展示image, 不過, 有兩中情況需要做些額外的工作:
- 如果你將image作為自定義view的部分展示. 你需要在
drawRect:中將image繪制到view中. - 如果你想離屏(延遲顯示, 或者保存到文件)渲染image, 那么必須創(chuàng)建一個bitmap上下文環(huán)境.
繪制image
為了獲得最大的性能,如果可以使用UIImageView類顯示圖像的需要,則應(yīng)該使用此圖像對象來初始化UIImageView對象。但是,如果需要顯式繪制圖像,則可以存儲圖像并在視圖的drawRect:方法中使用它。
下面的示例演示如何從應(yīng)用程序包中加載圖像。
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"myImage" ofType:@"png"];
UIImage *myImageObj = [[UIImage alloc] initWithContentsOfFile:imagePath];
// Store the image into a property of type UIImage *
// for use later in the class's drawRect: method.
self.anImage = myImageObj;
要在視圖的drawRect:方法中顯式地繪制結(jié)果圖像,可以使用UIImage中可用的任何繪圖方法。這些方法允許您指定在視圖中要繪制圖像的位置,因此不需要在繪制之前創(chuàng)建和應(yīng)用單獨的轉(zhuǎn)換。
下面的代碼片段在視圖中的點(10, 10)繪制上方加載的圖像。
- (void)drawRect:(CGRect)rect {
...
// Draw the image.
[self.anImage drawAtPoint:CGPointMake(10, 10)];
}
重要: 如果你使用
CGContextDrawImage函數(shù)來直接繪制bitmap圖像, 那么圖像會在y軸方向翻轉(zhuǎn)了. 因為CoreGraphic中的坐標(biāo)系是LLO型的, 想繪制正常的圖像, 那么你需要對Graphic context做變換, 前面內(nèi)容已經(jīng)講過.
使用Bitmap圖像上下文創(chuàng)建新的image
多數(shù)情況下, 你是將內(nèi)容繪制到屏幕上以便顯示. 但是有時候需要將一些內(nèi)容繪制到屏幕外緩沖區(qū). 例如, 你可能希望創(chuàng)建一個現(xiàn)有圖像的縮略圖, 然后繪制到緩沖區(qū)以便將其保存到文件等. 為了支持這些需求, 你可以創(chuàng)建一個bitmap圖像上下文, 使用UIKit或Core Graphic框架對其進(jìn)行繪制, 然后從上下文中獲取圖像對象.
在UIKit中, 步驟如下:
- 調(diào)用
UIGraphicsBeginImageContextWithOptions來創(chuàng)建一個bitmap圖像上下文然后push進(jìn)Graphic堆棧.- 第一個參數(shù)
size, 傳一個CGSize來確定繪圖區(qū)域大小 - 第二個參數(shù)
opaque, 如果你的image包含透明的部分,傳NO; 否則, 傳YES, 這樣性能也能提升 - 第三參數(shù)
scale, 傳0.0, 如果比bitmap已經(jīng)適配屏幕, 也可按需傳入其他值.
- 第一個參數(shù)
舉個例子, 下面的代碼片段創(chuàng)建一個200x200像素的bitmap(像素量有scale*點數(shù))
UIGraphicsBeginImageContextWithOptions(CGSizeMake(100.0,100.0), NO, 2.0);
注意:你平常應(yīng)該避免使用名稱類似
UIGraphicsBeginImageContext的函數(shù)(除了作為向后兼容性的回退之外), 因為它總是創(chuàng)建scale為1.0的像素, 如果底層設(shè)備具有高分辨率屏幕, 使用上面的函數(shù)創(chuàng)建的圖像看起來可能不會那么平滑.
- 使用UIKit或者Core Graphic的繪圖方式將圖像繪制到新創(chuàng)建的圖形上下文中
- 調(diào)用
UIGraphicsGetImageFromCurrentImageContext函數(shù)來創(chuàng)建和返回一個你繪制的UIImage對象. 你可以繼續(xù)繪制內(nèi)容然后調(diào)用該方法獲取新的圖片 - 調(diào)用
UIGraphicsEndImageContext函數(shù)pop出當(dāng)前bitmap圖形上下文.
代碼4-1中的方法從網(wǎng)上下載一張圖片然后將其繪制到上下文, 縮小APP icon的圖片大小. 從bitmap數(shù)據(jù)中獲取UIImage對象, 然后賦值給一個變量. 要注意bitmap(函數(shù)UIGraphicsBeginImageContextWithOptions的第一個參數(shù))中的size和繪制內(nèi)容(imageRect的size)的size要相符. 如果內(nèi)容的size要比bitmap大, 一部分內(nèi)容將被裁剪掉
代碼清單4-1 將縮小的圖像繪制到位圖上下文并獲得結(jié)果圖像
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
UIImage *image = [[UIImage alloc] initWithData:self.activeDownload];
if (image != nil && image.size.width != kAppIconHeight && image.size.height != kAppIconHeight) {
CGRect imageRect = CGRectMake(0.0, 0.0, kAppIconHeight, kAppIconHeight);
UIGraphicsBeginImageContextWithOptions(itemSize, NO, [UIScreen mainScreen].scale);
[image drawInRect:imageRect];
self.appRecord.appIcon = UIGraphicsGetImageFromCurrentImageContext(); // UIImage returned.
UIGraphicsEndImageContext();
} else {
self.appRecord.appIcon = image;
}
self.activeDownload = nil;
[image release];
self.imageConnection = nil;
[delegate appImageDidLoad:self.indexPathInTableView];
}
您還可以調(diào)用Core Graphics函數(shù)來繪制生成的位圖圖像的內(nèi)容;清單3-2中的代碼片段給出了一個示例,該代碼片段繪制了PDF頁面的縮放圖像。注意,代碼在調(diào)用CGContextDrawPDFPage之前翻轉(zhuǎn)圖形上下文,以使繪制的圖像與UIKit的默認(rèn)坐標(biāo)系統(tǒng)對齊。
代碼清單3-2 使用Core Graphic函數(shù)往bitmap上下文中繪制內(nèi)容
// Other code precedes...
CGRect pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
pdfScale = self.frame.size.width/pageRect.size.width;
pageRect.size = CGSizeMake(pageRect.size.width * pdfScale, pageRect.size.height * pdfScale);
UIGraphicsBeginImageContextWithOptions(pageRect.size, YES, pdfScale);
CGContextRef context = UIGraphicsGetCurrentContext();
// First fill the background with white.
CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0);
CGContextFillRect(context,pageRect);
CGContextSaveGState(context);
// Flip the context so that the PDF page is rendered right side up
CGContextTranslateCTM(context, 0.0, pageRect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// Scale the context so that the PDF page is rendered at the
// correct size for the zoom level.
CGContextScaleCTM(context, pdfScale,pdfScale);
CGContextDrawPDFPage(context, page);
CGContextRestoreGState(context);
UIImage *backgroundImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
backgroundImageView = [[UIImageView alloc] initWithImage:backgroundImage];
// Other code follows...
如果你喜歡全用Core Graphic來繪制內(nèi)容, 那么你可以使用CGBitmapContextCreate函數(shù)來創(chuàng)建上下文, 并將圖像內(nèi)容會知道上下文中. 完成繪圖后, 調(diào)用CGBitmapContextCreateImage函數(shù)來獲取CGImageRef對象. 使用直接使用Core Graphic來繪制圖像, 也可以創(chuàng)建UIImage對象. 最后調(diào)用CGContextRelease函數(shù)來釋放上文對象.