畫圖

IOS繪圖詳解

2013-04-19 12:54:07|  分類:IOS|舉報|字號訂閱

14.1 Quartz概述

14.2 繪製基本幾何圖形

14.3 繪製圖像和文本

14.4 座標

14.5 變換

14.6 圖像拾取器

14.1 Quartz概述

Quartz是Mac OS X的Darwin核心之上的繪圖層,有時候也認爲是CoreGraphics。共有兩種部分組成Quartz:

Quartz Compositor,合成視窗系統,管理和合成幕後視窗影像來建立Mac OS X使用者接口。

Quartz 2D,是iOS和Mac OS X環境下的二維繪圖引擎。

涉及內容包括:基於路徑的繪圖,透明度繪圖,遮蓋,陰影,透明層,顏色管理,防鋸齒渲染,生成PDF,以及PDF元數據相關處理。

14.2 繪製基本幾何圖形

視圖繪製

   在iOS上,所有的繪製,無論是否採用OpenGL、Quartz、UIKit、或者 Core Animation—都發生在UIView對象的區域內。

視圖定義繪製發生的屏幕區域。如果您使用系統提供的視圖,繪製工作會自動得到處理。然而,如果您定義自己的定製視圖,則必須自行提供繪製代碼。

對於使用OpenGL進行繪製的應用程序,一旦建立了渲染表面,就必須使用OpenGL指定的繪製模型。

視圖繪製週期

   描繪系統會調用UIView對象的drawRect:方法,並向它傳入一個包含需要重畫的視圖區域的矩形。觸發視圖更新的動作有如下幾種:

對遮擋您的視圖的其它視圖進行移動或刪除操作。

將視圖的hidden屬性聲明設置爲NO,使其從隱藏狀態變爲可見。

將視圖滾出屏幕,然後再重新回到屏幕上。

顯式調用視圖的setNeedsDisplay或者setNeedsDisplayInRect:方法。

setNeedsDisplay是更新整個視圖,

setNeedsDisplayInRect是更新視圖的部分區域。

視圖繪製實例FirstQuartz2D

wps_clip_p_w_picpath-14312

自定義視圖的h文件

@interface MyView : UIView {    }@end

自定義視圖的m文件

複製代碼

@implementation MyView- (void)drawRect:(CGRect)rect {        CGContextRef context = UIGraphicsGetCurrentContext();        CGContextMoveToPoint (context, 75, 10);     CGContextAddLineToPoint (context, 10, 150);     CGContextAddLineToPoint (context, 160, 150);         // Closing the path connects the current point to the start of the current path.    CGContextClosePath(context);    // And stroke the path    [[UIColor blackColor] setStroke];     //CGContextStrokePath(context);    [[UIColor redColor] setFill];     CGContextDrawPath(context, kCGPathFillStroke);    //kCGPathFillStroke,kCGPathFill,kCGPathStroke    }@end

複製代碼

CGContextRef context = UIGraphicsGetCurrentContext();可以獲得圖形上下文。

CGContextMoveToPoint、CGContextAddLineToPoint兩個函數是構建描繪路徑。

CGContextClosePath(context);函數是閉合描繪路徑。

CGContextStrokePath函數是爲閉合路徑描邊。

[[UIColor blackColor] setStroke]設置描邊的顏色。

[[UIColor redColor] setFill]設置要填充顏色。

CGContextDrawPath(context, kCGPathFillStroke);設置描繪路徑方式。常用的還有:

kCGPathFill和kCGPathStroke

圖形上下文

 在調用您提供的drawRect:方法之前,視圖對象會自動配置其繪製環境,使您的代碼可以立即進行繪製。作爲這些

配置的一部分,UIView對象會爲當前繪製環境創建一個圖形上下文(對應於CGContextRef封裝類型)。

 該圖形上下文包含繪製系統執行後續繪製命令所需要的信息,定義了各種基本的繪製屬性,比如繪製使用的顏色、

裁剪區域、線的寬度及風格信息、字體信息、合成選項、以及幾個其它信息。

繪製路徑

 路徑用於描述由一序列線和Bézier曲線構成的2D幾何形狀。Core Graphics中也有一些用於創建簡單路徑(比如矩形和橢圓形)的便利函數。對於更爲複雜的路徑,必須用Core Graphics框架提供的函數自行創建。

 Bézier曲線是法國數學家“貝塞爾”在工作中發現,任何一條曲線都可以通過與它相切的控制線兩端的點的位置來定義。

Bézier曲線

wps_clip_p_w_picpath-26605

Bézier曲線實例BezierCurve

wps_clip_p_w_picpath-32456

複製代碼

- (void)drawRect:(CGRect)rect {        CGContextRef cgContext = UIGraphicsGetCurrentContext();        //CGContextBeginPath(cgContext);    CGContextMoveToPoint(cgContext, 333, 0);    CGContextAddCurveToPoint(cgContext, 333, 0, 332, 26, 330, 26);    CGContextAddCurveToPoint(cgContext, 330, 26, 299, 20, 299, 17);    CGContextAddLineToPoint(cgContext, 296, 17);    CGContextAddCurveToPoint(cgContext, 296, 17, 296, 19, 291, 19);    CGContextAddLineToPoint(cgContext, 250, 19);    CGContextAddCurveToPoint(cgContext, 250, 19, 241, 24, 238, 19);    CGContextAddCurveToPoint(cgContext, 236, 20, 234, 24, 227, 24);    CGContextAddCurveToPoint(cgContext, 220, 24, 217, 19, 216, 19);    CGContextAddCurveToPoint(cgContext, 214, 20, 211, 22, 207, 20);    CGContextAddCurveToPoint(cgContext, 207, 20, 187, 20, 182, 21);    CGContextAddLineToPoint(cgContext, 100, 45);    CGContextAddLineToPoint(cgContext, 97, 46);    CGContextAddCurveToPoint(cgContext, 97, 46, 86, 71, 64, 72);    CGContextAddCurveToPoint(cgContext, 42, 74, 26, 56, 23, 48);    CGContextAddLineToPoint(cgContext, 9, 47);    CGContextAddCurveToPoint(cgContext, 9, 47, 0, 31, 0, 0);        CGContextStrokePath(cgContext);}

複製代碼

14.3 繪製圖像和文本

UIImages的-drawRect:方法繪製圖像:

- [UIImage drawAtPoint:(CGPoint)point]

- [UIImage drawInRect:(CGRect)rect]

- [UIImage drawAsPatternInRect:(CGRect)rect]

NSString的-drawRect:方法繪製文本:  

- [NSString drawAtPoint:(CGPoint)point withFont:(UIFont *)font]

實例DrawImage

wps_clip_p_w_picpath-11683

複製代碼

#import"MyView.h"@implementation MyView- (void)drawRect:(CGRect)rect {        NSString* p_w_picpathPath = [[NSBundle mainBundle] pathForResource:@"dog" ofType:@"png"];    UIImage* myImageObj = [[UIImage alloc] initWithContentsOfFile:p_w_picpathPath];    //[myImageObj drawAtPoint:CGPointMake(0, 0)];    [myImageObj drawInRect:CGRectMake(0, 0, 320, 480)];        NSString *s = @"我的小狗";        [s drawAtPoint:CGPointMake(100, 0) withFont:[UIFont systemFontOfSize:34.0]];}@end

複製代碼

寫字實例Draw

wps_clip_p_w_picpath-23850

Dot對象

複製代碼

//--h@interface Dot : NSObject {  CGFloat x;  CGFloat y;}@property(assign) CGFloat x;@property(assign) CGFloat y;@end//--m#import"Dot.h"@implementation Dot@synthesize x;@synthesize y;@end

複製代碼

DrawView.h

複製代碼

#import <UIKit/UIKit.h>@interface DrawView : UIView {  NSMutableArray *dots;}@property(nonatomic, retain) NSMutableArray *dots;@end

複製代碼

DrawView.m

複製代碼

#import"DrawView.h"#import"Dot.h"@implementation DrawView@synthesize dots;- (NSMutableArray *)dots {    if(nil == dots) {        self.dots = [NSMutableArray array];    }    return dots;}//START:code.DrawView.drawRect- (void)drawRect:(CGRect)rect {    CGContextRef ctx = UIGraphicsGetCurrentContext();    CGContextSetFillColorWithColor(ctx, [[UIColor blueColor] CGColor]);    for(Dot *dot in self.dots) {        CGContextAddArc(ctx, dot.x, dot.y, 5.0f, 0.0f, 2.0f * M_PI, YES);        CGContextFillPath(ctx);    }    }//END:code.DrawView.drawRect- (void)dealloc {    self.dots = nil;    [super dealloc];}

複製代碼

drawRect方法中將dots集合中的Dot對象取出,一個一個在屏幕上面畫出來。

CGContextAddArc(ctx, dot.x, dot.y, 5.0f, 0.0f, 2.0f * M_PI, YES);函數是繪製弧形。

CGContextFillPath(ctx);填充路徑。

複製代碼

//START:code.DrawView.touchesBegan- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {    UITouch *touch = [touches anyObject];    CGPoint location = [touch locationInView:self];    Dot *dot = [[[Dot alloc] init] autorelease];    dot.x = location.x;    dot.y = location.y;    //[self.dots removeAllObjects];    [self.dots addObject:dot];    [self setNeedsDisplay];}//END:code.DrawView.touchesBegan//START:code.DrawView.touchesMoved- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {    UITouch *touch = [touches anyObject];    CGPoint location = [touch locationInView:self];    Dot *dot = [[[Dot alloc] init] autorelease];    dot.x = location.x;    dot.y = location.y;    [self.dots addObject:dot];    [self setNeedsDisplay];}//END:code.DrawView.touchesMoved

複製代碼

14.4 座標

Quartz座標

Quartz技術最開始爲Mac OS X系統設計的圖形技術,它的座標原點位於左下角。

wps_clip_p_w_picpath-1616

UIKit座標

UIKit座標與Quartz不同,原點位於右上角。在iOS中的UIView等控件都是基於此座標,由於在UIView使用了Quartz座標有時候需要轉換。

wps_clip_p_w_picpath-5807

座標變換實例

wps_clip_p_w_picpath-29340

MyView.m文件

複製代碼

#import"MyView.h"@implementation MyView- (void)drawRect:(CGRect)rect {    NSString *path = [[NSBundle mainBundle] pathForResource:@"cat" ofType:@"jpg"];    UIImage *img = [UIImage p_w_picpathWithContentsOfFile:path];    CGImageRef p_w_picpath = img.CGImage;    CGContextRef context = UIGraphicsGetCurrentContext();    CGContextSaveGState(context);        CGRect touchRect = CGRectMake(0, 0, img.size.width, img.size.height);    CGContextDrawImage(context, touchRect, p_w_picpath);      CGContextRestoreGState(context);}@end

複製代碼

CGContextSaveGState是將當前圖形狀態要入到圖形堆棧。

CGContextDrawImage(context, touchRect, p_w_picpath)在上下文中繪製圖形。 CGContextRestoreGState回覆當前圖形狀態。

14.5 變換

運用變換

變換(transformation)修改了圖形上下文中繪製圖形的方式。可以通過移動、旋轉或縮放實現變換。

Quartz提供了多種形式的變換,其中主要:CTM(當前變換矩陣)變換和仿射(affine)變換。

CTM(current transformation matrix)變換,這種變換比較簡單,函數有:

CGContextRotateCTM,旋轉座標

CGContextScaleCTM,縮放座標

CGContextTranslateCTM,移動原點

移動變換

CGContextTranslateCTM (myContext, 100, 50)

wps_clip_p_w_picpath-23595

從對象角度沿着x軸正向移動100單位,沿着y軸正向移動50單位。

旋轉變換

static inline double radians (double degrees) {return degrees * M_PI/180;}

CGContextRotateCTM (myContext, radians(–45.));

wps_clip_p_w_picpath-9368

從對象角度:

在Quartz座標下正數爲逆時針旋轉,負數爲順時針旋轉。

在UIKit座標下正數爲順時針旋轉,負數爲逆時針旋轉。

縮放變換

CGContextScaleCTM (myContext, .5, .75);

wps_clip_p_w_picpath-14003

從對象角度:所有x座標縮小0.5,所有y座標縮小0.75。

修改MyView.m文件

複製代碼

#import"MyView.h"@implementation MyView- (void)drawRect:(CGRect)rect {    NSString *path = [[NSBundle mainBundle] pathForResource:@"cat" ofType:@"jpg"];    UIImage *img = [UIImage p_w_picpathWithContentsOfFile:path];    CGImageRef p_w_picpath = img.CGImage;    CGContextRef context = UIGraphicsGetCurrentContext();    CGContextSaveGState(context);        CGContextRotateCTM(context, M_PI);    CGContextTranslateCTM(context, -img.size.width, -img.size.height);        CGRect touchRect = CGRectMake(0, 0, img.size.width, img.size.height);    CGContextDrawImage(context, touchRect, p_w_picpath);      CGContextRestoreGState(context);}@end

複製代碼

仿射(affine)變換

仿射(affine)變換也是一種直角座標變換,重

用變換,經過多次變換(多次的矩陣相乘),

每一種變換都可以用矩陣表示,通過多次矩陣

相乘得到最後結果。仿射變換函數:

   CGAffineMakeRotation,創建旋轉矩陣仿射對象

   CGAffineMakeScale,創建縮放矩陣仿射對象

   CGAffineMakeTranslation,創建移動矩陣仿射對象

   CGAffineTransformRotate,旋轉矩陣仿射對象

   CGAffineTransformScale,縮放矩陣仿射對象

   CGAffineTransformTranslate,移動矩陣仿射對象

   CGContextConcatCTM,連接到CTM變換

使用仿射變換MyView.m

複製代碼

#import"MyView.h"@implementation MyView- (void)drawRect:(CGRect)rect {    NSString *path = [[NSBundle mainBundle] pathForResource:@"cat" ofType:@"jpg"];    UIImage *img = [UIImage p_w_picpathWithContentsOfFile:path];    CGImageRef p_w_picpath = img.CGImage;    CGContextRef context = UIGraphicsGetCurrentContext();    CGContextSaveGState(context);        CGAffineTransform myAffine = CGAffineTransformMakeRotation(M_PI);     myAffine = CGAffineTransformTranslate(myAffine, -img.size.width, -img.size.height);     CGContextConcatCTM(context, myAffine);        CGContextRotateCTM(context, M_PI);    CGContextTranslateCTM(context, -img.size.width, -img.size.height);        CGRect touchRect = CGRectMake(0, 0, img.size.width, img.size.height);    CGContextDrawImage(context, touchRect, p_w_picpath);      CGContextRestoreGState(context);}@end

複製代碼

14.6 圖像拾取器

圖像拾取器(Image Picker)是可以幫助你從圖片庫中選取圖片,也可以捕獲照相機圖片。

wps_clip_p_w_picpath-22106

wps_clip_p_w_picpath-8654

PhotoViewViewController.h

複製代碼

//START:code.PhotoViewController.h@interface PhotoViewViewController : UIViewController<UIImagePickerControllerDelegate> {    UIImageView *p_w_picpathView;    UIImagePickerController *p_w_picpathPicker;}@property(nonatomic, retain) IBOutlet UIImageView *p_w_picpathView;@property(nonatomic, retain) IBOutlet UIImagePickerController *p_w_picpathPicker;@end//END:code.PhotoViewController.h

複製代碼

需要實現UIImagePickerControllerDelegate協議。

需要定義UIImagePickerController控制器成員變量。

PhotoViewViewController.m

複製代碼

#import"PhotoViewViewController.h"@implementation PhotoViewViewController@synthesize p_w_picpathView;@synthesize p_w_picpathPicker;//START:code.PhotoViewController.touchesEnded:withEvent:- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {    if([[touches anyObject] tapCount] > 1) {        // bring up p_w_picpath grabberif([UIImagePickerController isSourceTypeAvailable:            UIImagePickerControllerSourceTypeCamera]) {            self.p_w_picpathPicker.sourceType = UIImagePickerControllerSourceTypeCamera;        } else {            self.p_w_picpathPicker.sourceType =            UIImagePickerControllerSourceTypePhotoLibrary;        }        //self.p_w_picpathPicker.allowsImageEditing = YES; //iOS 3之前        self.p_w_picpathPicker.allowsEditing = YES;                 [self presentModalViewController:self.p_w_picpathPicker animated:YES];     }}//END:code.PhotoViewController.touchesEnded:withEvent:

複製代碼

圖像選取器的sourceType屬性有:

UIImagePickerControllerSourceTypePhotoLibrary,圖片來源於“相簿”

UIImagePickerControllerSourceTypeCamera,來源於相機

UIImagePickerControllerSourceTypeSavedPhotosAlbum,來源於“相機膠捲”。

PhotoViewViewController.m

複製代碼

//START:code.PhotoViewController.didFinish- (void)p_w_picpathPickerController:(UIImagePickerController *)pickerdidFinishPickingMediaWithInfo:(NSDictionary *)info {    p_w_picpathView.p_w_picpath = [info objectForKey:UIImagePickerControllerEditedImage];     [self dismissModalViewControllerAnimated:YES]; }//END:code.PhotoViewController.didFinish//START:code.PhotoViewController.didCancel- (void)p_w_picpathPickerControllerDidCancel:(UIImagePickerController *)picker {    [self.p_w_picpathPicker dismissModalViewControllerAnimated:YES];}//END:code.PhotoViewController.didCancel- (void)dealloc {    self.p_w_picpathView = nil;    self.p_w_picpathPicker = nil;    [super dealloc];}

複製代碼

p_w_picpathPickerController:didFinishPickingMediaWithInfo:委託實現方法,當選擇完成時候調用。

p_w_picpathView.p_w_picpath = [info objectForKey:UIImagePickerControllerEditedImage];語句可以從圖片拾取器中獲得一個Image對象。

p_w_picpathPickerControllerDidCancel:是委託實現方法當點擊取消時候調用。


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