iOS 自定義繪製內容

一、Layer上下文
當UIView第一次顯示出來的時候,會調用view的drawRect方法,在drawRect方法中,可以獲取和當前視圖相關聯的圖形上下文,圖形上下文中已經包含了決定繪製的輸出目標,在UIView的drawRect方法中調用 UIGraphicsGetCurrentContext方法即可以獲取到上下文(Layer上下文);
當view的frame發生改變的時候,drawRect會被自動調用;自定義view的背景顏色如果是default color的話,在drawRect方法中,會有緩存,可以手動調用CGContextClearRect方法清除;

1.畫線

CGContextMoveToPoint(ctx, 10, 100);  // 起點
CGContextAddLineToPoint(ctx, 100, 100);  // 終點

線(繪製直線,實際上layer並沒有直接渲染出來,而只是保存了繪製的信息)
CGContextMoveToPoint方法默認會給我們創建一個路徑,之後的操作會把點添加到路徑中;
2.繪製圓和圓弧

CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 50, 50));  // 畫圓
CGContextAddArc(ctx, 50, 50, 50, 0, M_PI_2, 0);  // 畫圓弧,前兩個參數爲圓心,接着的參數分別爲半徑,開始弧度,結束弧度,畫圓弧方向(1逆時針,0順時針)

3.繪製矩形

CGContextAddRect(ctx, CGRectMake(10, 10, 100, 100));  
// 繪製矩形,之後需要調用渲染方法(參見第7條);
CGContextStrokeRect(ctx, CGRectMake(10, 10, 100, 100));  
// 繪製矩形 | Fill,自動渲染,不需要手動調用渲染方法;
UIRectFill(CGRectMake(10, 10, 100, 100));  
// 通過OC的方法繪製實心四邊形,該方法沒有空心的方法;

4.繪製文字

dict[NSForegroundColorAttributeName] = [UIColor redColor];  // 文字顏色
dict[NSBackgroundColorAttributeName] = [UIColor redColor];  // 文字背景
dict[NSFontAttributeName] = [UIFont systemFontOfSize:14];  //  文字大小
[str drawAtPoint:CGPointMake(50, 50) withAttributes:dict]; 
// 繪製到指定點
[str drawInRect:CGRectMake(50, 50, 100, 100) withAttributes:nil]; 
// 將文字繪製到指定範圍內,如果一行顯示不完會自動換行,當文字超出範圍後不再顯示;

5.繪製圖片

[image drawInRect:CGRectMake(50, 50, 100, 100)];  
// 利用drawInRect方法繪製圖片渲染到layer,拉伸原有圖片;
[image drawAtPoint:CGPointMake(50, 50)];  // 將圖片繪製到指定位置;
[image drawAsPatternInRect:CGRectMake(0, 0, 200, 200)];  // 平鋪原有圖片;

6.設置繪圖信息/樣式
(1). 顏色

CGContextSetRGBStrokeColor(ctx, 1,0, 0, 0, 1,0);  // 設置繪圖顏色
CGContextSetRGBFillColor(ctx, 1,0, 0, 0, 1,0);
[[UIColor redColor] setFill]; // 調用OC的方法設置繪圖的填充顏色
[[UIColor redColor] setStroke];
[[UIColor redColor] set];  // 同時設置實心和空心

(2). 樣式

CGContextSetLineWidth(ctx, 10);  // 設置線寬
CGContextSetLineCap(ctx, CGLineCap);  // 設置線的起點和終點的樣式
CGContextSetLineJoin(ctx, CGLineJoin);  // 設置線的拐點樣式
CGContextClosePath(ctx);  // 根據設置的線的點,關閉圖形

7.渲染

CGContextStrokePath(ctx);  // 繪製圖形(渲染到view上),繪製一條空心的線;
CGContextFillPath(ctx);  // 渲染圖形(填充)

8.貝賽爾曲線
需要三個點座標,分別是控制器,當前點,結束點;

CGContextMoveToPoint(ctx, currentX, currentX);  // 首先移動到當前點;
CGContextAddQuadCurveToPoint(ctx, controllerX, controllerY, endX, endY);  // controllerX|controllerY 是控制點位置,endX|endY是結束點位置;

9.繪製樣式保存

CGContextSaveGState(ctx);  // 保存一份純淨的上下文,調用一次此方法會就會拷貝一個上下文到棧中;
CGContextRestoreGState(ctx);  // 還原開始保存的純淨的上下文

10.矩陣操作
設置矩陣操作必須放置到添加繪圖信息之前;

CGContextRotateCTM(ctx ,angle);
CGContextScaleCTM(ctx, scaleX, scaleY);
CGContextTranslateCTM(ctx , 0, 250);

在上面的操作之後,再調用比如moveToPoint等方法;
11.Clip
指定範圍也就是指定剪切的方法一定要在渲染範圍之前調用;

CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 50, 50)); // 往上下文中添加一個圓形區域;
CGContextClip(ctx);  // 指定上下文中可以顯示內容的範圍;

以上操作之後再進行moveToPoint、addPoint…,再進行渲染;
補充:如果在剪切之前有繪製操作,則剪切前的內容將不會改變,而是原樣顯示;

CGContextClearRect(ctx, rect);  // 清空某個區域的內容
// C中的路徑
CGMutablePathRef path = CGPathCreateMutable();  // 創建路徑;
CGPathMoveToPoint(path, NULL, 10, 10);  // 設置起點;
CGPathAddLineToPoint(path, NULL, 100, 100);  // 移動到某一點;
CGContextAddPath(ctx, path);  // 添加path到上下文中;
CGContextStrokePath(ctx);  // 渲染;
CGPathAddEllipseInRect(path, NULL, CGRectMake(10, 10, 100, 100));  // 添加畫圓的路徑;

注意:
但凡通過quarzt2d中帶有create/copy/retain方法創建出來的對象都必須手動釋放,有兩種方法;

CGPathRelease(path);  // 釋放對象;
CFRelease(path);  // 釋放對象2;

12.OC中的Path

UIBezierPath *path = [UIBezierPath bezierPath];  // 創建路徑
[path moveToPoint:CGPointMake(20, 20)];  // 設置起點
[path addLineToPoint:CGPointMake(100, 100)];  // 移動到某一點
[path setLineCapStyle:kCGLineCapRound];  // 設置線的樣式;
[path setLineWidth:10];  // 線寬;
[[UIColor redColor] set]; // 顏色;
[path stroke];  // 渲染

在stroke渲染之前,也可以調用C方法設置CGContextRef對象的樣式,比如[color set];

二、圖形上下文
1.創建bitmap上下文

UIGraphicsBeginImageContextWithOptions(CGSize size, Bool opaque, CGFloat scale);
// size:指定將來創建出來的bitmap大小
// opaque:YES:不透明,如果某區域沒內容,則顯示黑色;
// scale:縮放比例,0表示不縮放

創建出來的bitmap就對應一個UIImage
2.獲取所創建的bitmap上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

3.繪圖

CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 100, 100));

4.渲染

CGContextStrokePath(ctx);

5.獲取生成的圖片

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

6.保存圖片
保存繪製好的圖片到文件中,先將圖片轉換爲二進制數據,然後再將圖片寫到文件中;

NSData *data = UIImageJPEGRepresentation(image, 1);  // jpeg
NSData *data = UIImagePNGRepresentation(image);  // png
[data writeToFile:@"path" atomically:YES];

添加水印用一中的方法draw文字,draw圖片實現水印功能;

7.截圖

UIGraphicsBeginImageContextWithOptions(cgsize, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];  // 將view的layer所渲染的內容渲染到當前的ContextRef中;
// 取得圖片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

保存圖片到相冊,回調方法不需自定義,直接實現系統推薦的回調方法;

UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
-(void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
}

8.切割圖片

CGImageRef subimageRef= CGImageCreateWithImageInRect(image.CGImage, CGRectMake(0, 0, 640, 480));;
//
UIImage *subImage = [UIImage imageWithCGImage:subimageRef];
[UIImagePNGRepresentation(subImage) writeToFile:@“path”atomically:YES];

9.關閉圖形上下文

UIGraphicsEndImageContext();  // 關閉圖片上下文
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章