實作圓形圖檔的裁切有多種方法,可以直接設定
layer.cornerRadius
,但這樣會造成離屏渲染,耗費記憶體。在此不詳述離屏渲染,想看的戳進去吧:iOS離屏渲染研究
先來個簡單例子:實作圓形圖檔的裁切
- (UIImage *)circleImage:(UIImage *)image {
if (!image) return nil;
// 開始上下文,下面不使用時一定要關閉,從上下文棧中移除
UIGraphicsBeginImageContextWithOptions(image.size, NO
,[UIScreen mainScreen].scale);
CGContextRef context = UIGraphicsGetCurrentContext();
// 添加鑲邊
CGContextSetLineWidth(context, );
CGContextSetStrokeColorWithColor(context, [UIColor yellowColor].CGColor);
//裁切
CGRect rect = CGRectMake(, , image.size.width, image.size.height);
CGContextAddEllipseInRect(context, rect);
CGContextClip(context);
// 在圓區内畫出image原圖
[image drawInRect:rect];
// 圍繞目前路徑畫一條線,鑲邊線,注意在調用strokePath之前必須先添加線,fillPath也一樣要先添加線才可操作
CGContextAddEllipseInRect(context, rect);
CGContextStrokePath(context);
//從上下文環境中擷取切好的圖檔
UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext();
// 使用了beginImgacontext需要關閉上下文 并從上下文棧中移除
UIGraphicsEndImageContext();
return newImg;
}
調用方式如:
UIImage *image = [UIImage imageNamed:@"welcome.png"];
UIImageView *imagView = [[UIImageView alloc] initWithFrame:CGRectMake(, , , )];
imagView.image = [self circleImage:image];
[self.view addSubview:imagView];
一直對上下文操作視圖感到好奇,這下便檢視部分文檔資料,簡單翻譯了下,如有不合理歡迎指正:
傳回:
目前的圖形上下文
描述:
預設情況下目前的圖形上下文為nil,首先調用到它的是drawRect:方法,
視圖控件将一個有效的上下文壓到一個棧中,使其成為目前上下文, 如果你不使用一個控件對象來進行繪畫,
那麼你便需要手動将一個有效的上下文壓到棧中通過使用UIGraphicsPushContext函數
這個方法可能從你app的任何線程中調用。
使一個特殊的上下文成為目前的上下文
描述: 你可以使用這個功能去儲存之前的圖形上下文狀态,并且使一個上下文成為目前的上下文,
使用這個方法需要配對使用UIGraphicsPopContext方法 這個方法可能從你的app的任何線程中調用
從上下文棧中移除目前的上下文,恢複使用之前的上下文
UIGraphicsBeginImageContext(size)
建立一個基于位圖的圖形上下文,并使之成為目前的上下文
parameters:
size: 新位圖上下文的尺寸,這個代表了通過 UIGraphicsGetImageFromCurrentImageContext方法傳回的圖檔的尺寸
描述:
這個方法相當于調用了UIGraphicsBeginImageContextWithOptions方法,
并且opaque參數設定為NO,并且一個scale參數為1.0 這個方法可能從你的app的任何線程中調用
UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)
建立一個基于位圖的圖形上下文同時附帶有相應的選擇
parameters:
size: 新的位圖上下文的尺寸(以點來作為量算機關)。
這展現在在UIGraphicsGetImageFromCurrentImageContext函數傳回的圖檔的尺寸。
為了得到位圖的的像素尺寸,你必須以寬度和高度乘以scale參數。
opaque: 一個BOOL值的标志标志着位圖是否為半透明。如果你知道位圖是完全的不透明,
指派YES去忽略掉alpha通道并且優化位圖的存儲空間。
指派為NO意味着位圖必須要包含alpha通道去掌握着部分的透明像素。
scale: 這個scale元素去應用到位圖中,如果你将其設定為0.0f,
那麼就會以系統裝置螢幕尺寸的的scale作為标準。
讨論:
你可以使用這個方法去配置繪畫環境送出到位圖中。
這個位圖是ARGB32-bit整型像素格式使用主byte次序。如果opaque參數設定為YES,
這個alpha通道被忽略并且被認為是完全不透明(kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrer32Host)。
不然每一個像素使用premultipledARGB格式(kCGImageAlphaPremultipledFirst | kCGBitmapByteOrder32Host).
這個環境同時使用了預設的UIKit視圖的坐标系統,它的原點是在左上角,
正軸是原點向下及向右。這個提供到的scale因為同樣應用到坐标系統及得到的結果圖檔。
這個繪畫環境會被立刻push到圖形上下文。
當 目前上下文是通過這個方法生成的,你便可以調用UIGraphicsGetImageFromCurrentImageContext
函數去取回基于目前上下文的圖檔對象。當你不再改正上下文你必須去調用UIGraphicsEndImageContext方法去清理位圖繪畫環境并且從上下文棧中移除。
你不應該使用UIGraphicsPopContext函數去從棧上移除上下文。
在大多數其他情況,這個圖形上下文建立與其他一樣,你可以改變上下文通過
push或pop其他圖形上下文,你一樣可以通過UIGraphicsGetCurrentContext函數。
這個函數可以被任何線程的app調用
UIGraphicsGetImageFromCurrentImageContext
傳回一個基于目前位圖上下文中的内容
Return Value:
一個圖檔對象包含目前圖檔上下文中的内容
讨論:
你隻能在一個位圖上下文為目前上下文時才能調用這個方法。
如果目前上下文為nil或者不是通過調用UIGraphicsBeginImageContext來調用的,那麼這個函數便傳回nil.
這個函數可以被app的任何線程調用。
UIGraphicsEndImageContext
從上下文棧頂部移除目前的位圖上下文
注: 你可以使用這個方法來清理通過UIGraphicsBeginImageContext函數建立的上下文并且可以移除在棧頂部并基于位圖的上下文。
如果目前上下文不是通過UIGraphicsBeginImageContext函數建立,那麼這個方法什麼都不會去做。