上下文繪圖,濾鏡簡單使用

碼路芽子發表於2018-07-04

一、drawRect繪製功能

1.繪製直線

/** (這個方法在loadView、viewDidLoad方法後執行) */
- (void)drawRect:(CGRect)rect {
    
    /** 1.獲取上下文 */
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    /** 2.建立路徑物件 */
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, nil, 20, 50);/** 移動到指定位置(設定路徑起點) */
    CGPathAddLineToPoint(path, nil, 20, 100);/** 繪製一個直線(從起始位置開始) */
    CGPathAddLineToPoint(path, nil, 300, 100);/** 繪製另外一條直線,從上一條的終點開始 */
    
    /** 3.新增路徑到上下文 */
    CGContextAddPath(context, path);
    
    /** 4.設定推行上下文屬性 */
    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1);/** 設定觸筆的顏色 */
    CGContextSetRGBFillColor(context, 1.0, 0, 0, 1);/** 設定填充顏色 */
    CGContextSetLineWidth(context, 2.0);/** 設定線條寬度 */
    CGContextSetLineCap(context, kCGLineCapRound);/** 設定頂點樣式,(20,50)和(300,100)是頂點 */
    CGContextSetLineJoin(context, kCGLineJoinRound);/** 設定連線點樣式,(20,100)是連線點 */
    
    /* 設定線段樣式
     phase:虛線開始的位置 
     lengths:虛線長度間隔(例如下面的定義說明第一條線段長度8,然後間隔3重新繪製8點的長度線段,當然這個陣列可以定義更多元素) 
     count:虛線陣列元素個數 
     */
    
    CGFloat lengths[2] = { 18, 9 };
    CGContextSetLineDash(context, 0, lengths, 2);
    
    /* 設定陰影
     context:圖形上下文 
     offset:偏移量 blur:模糊度 
     color:陰影顏色 
     */
    CGColorRef color = [UIColor grayColor].CGColor;//顏色轉化,由於Quartz 2D跨平臺,所以其中不能使用UIKit中的物件,但是UIkit提供了轉化方法
    CGContextSetShadowWithColor(context, CGSizeMake(2, 2), 0.8, color);
    
    /** 5.繪製影象到指定圖形上下文 */
    /*CGPathDrawingMode是填充方式,列舉型別 
     kCGPathFill:只有填充(非零纏繞數填充),不繪製邊框 
     kCGPathEOFill:奇偶規則填充(多條路徑交叉時,奇數交叉填充,偶交叉不填充) 
     kCGPathStroke:只有邊框 
     kCGPathFillStroke:既有邊框又有填充 
     kCGPathEOFillStroke:奇偶填充並繪製邊框 */
    
    CGContextDrawPath(context, kCGPathFillStroke);//最後一個引數是填充型別
    
    
    /** 6.釋放物件 */
    CGPathRelease(path);
}
複製程式碼

精簡繪製直線

- (void)drawLine2 {
    //1.獲得圖形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    //2.繪製路徑(相當於前面建立路徑並新增路徑到圖形上下文兩步操作)
    CGContextMoveToPoint(context, 20, 50);
    CGContextAddLineToPoint(context, 20, 100);
    CGContextAddLineToPoint(context, 300, 100);
    
    //封閉路徑:a.建立一條起點和終點的線,不推薦
    //CGPathAddLineToPoint(path, nil, 20, 50);
    //封閉路徑:b.直接呼叫路徑封閉方法
    CGContextClosePath(context);
    //3.設定圖形上下文屬性
    [[UIColor redColor]setStroke];//設定紅色邊框
    [[UIColor greenColor]setFill];//設定綠色填充
    //[[UIColor blueColor]set];//同時設定填充和邊框色
    
    //4.繪製路徑
    CGContextDrawPath(context, kCGPathFillStroke);
}
複製程式碼

2. 繪製橢圓

#pragma mark - 繪製橢圓
-(void)drawEllipse:(CGContextRef)context {
    
    //新增物件,繪製橢圓(圓形)的過程也是先建立一個矩形
    
    CGRect rect = CGRectMake(50, 50, 220.0, 200.0);
    CGContextAddEllipseInRect(context, rect); //設定屬性
    [[UIColor purpleColor]set]; //繪製
    CGContextDrawPath(context, kCGPathFillStroke);
}
複製程式碼

3. 繪製弧形

#pragma mark 繪製弧形
-(void)drawArc:(CGContextRef)context{
    /*新增弧形物件 x:中心點x座標 y:中心點y座標 radius:半徑 startAngle:起始弧度 endAngle:終止弧度 closewise:是否逆時針繪製,0則順時針繪製 */
    CGContextAddArc(context, 160, 160, 100.0, 0.0, M_PI_2, 1);
    //設定屬性
    [[UIColor yellowColor]set];
    //繪製
    CGContextDrawPath(context, kCGPathFillStroke);
}
複製程式碼

4. 繪製貝塞爾曲線

#pragma mark 繪製貝塞爾曲線 
-(void)drawCurve:(CGContextRef)context {
    
    //繪製曲線
    CGContextMoveToPoint(context, 20, 100);
    //移動到起始位置
    
    /*繪製二次貝塞爾曲線 c:圖形上下文 cpx:控制點x座標 cpy:控制點y座標 x:結束點x座標 y:結束點y座標 */
    CGContextAddQuadCurveToPoint(context, 160, 0, 300, 100);
    CGContextMoveToPoint(context, 20, 500);
    
    /*繪製三次貝塞爾曲線 c:圖形上下文 cp1x:第一個控制點x座標 cp1y:第一個控制點y座標 cp2x:第二個控制點x座標 cp2y:第二個控制點y座標 x:結束點x座標 y:結束點y座標 */
    CGContextAddCurveToPoint(context, 80, 300, 240, 500, 300, 300);
    //設定圖形上下文屬性
    [[UIColor yellowColor]setFill];
    [[UIColor redColor]setStroke];
    //繪製路徑
    CGContextDrawPath(context, kCGPathFillStroke);
}
複製程式碼

5. 繪製文字

-(void)drawText:(CGContextRef)context {
    //繪製到指定的區域內容
    NSString *str=@"Star Walk is the most beautiful stargazing app you’ve ever seen on a mobile device. It will become your go-to interactive astro guide to the night sky, following your every movement in real-time and allowing you to explore over 200, 000 celestial bodies with extensive information about stars and constellations that you find.";

    CGRect rect= CGRectMake(20, 50, 280, 300);
    UIFont *font=[UIFont systemFontOfSize:18];//設定字型
    UIColor *color=[UIColor redColor];//字型顏色
    NSMutableParagraphStyle *style=[[NSMutableParagraphStyle alloc]init];//段落樣式
    NSTextAlignment align=NSTextAlignmentLeft;//對齊方式
    style.alignment = align;

    [str drawInRect:rect withAttributes:@{NSFontAttributeName:font,NSForegroundColorAttributeName:color,NSParagraphStyleAttributeName:style}];
}
複製程式碼

6.影象繪製

#pragma mark - 影象繪製
-(void)drawImage:(CGContextRef)context {
    UIImage *image=[UIImage imageNamed:@"image2.jpg"];
    //從某一點開始繪製
    [image drawAtPoint:CGPointMake(10, 50)]; //繪製到指定的矩形中,注意如果大小不合適會會進行拉伸
    //[image drawInRect:CGRectMake(10, 50, 300, 450)]; //平鋪繪製
    //[image drawAsPatternInRect:CGRectMake(0, 0, 320, 568)];
}
複製程式碼

二、繪製漸變檢視

#import "ShadeView.h"
#define TILE_SIZE 20
@implementation ShadeView

-(void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
//     [self drawLinearGradient:context];
//    [self drawRadialGradient:context];
//    [self drawBackgroundWithColoredPattern:context];
    [self drawImage2:context];

}

#pragma mark 線性漸變 
-(void)drawLinearGradient:(CGContextRef)context {
    //使用rgb顏色空間
    CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
    
    /*指定漸變色 
     space:顏色空間 
     components:顏色陣列,注意由於指定了RGB顏色空間,那麼四個陣列元素表示一個顏色(red、green、blue、alpha), 如果有三個顏色則這個陣列有4*3個元素 
     locations:顏色所在位置(範圍0~1),這個陣列的個數不小於components中存放顏色的個數 
     count:漸變個數,等於locations的個數 
     */
    CGFloat compoents[12] = { 248.0/255.0, 86.0/255.0, 86.0/255.0, 1, 249.0/255.0, 127.0/255.0, 127.0/255.0, 1, 1.0,1.0,1.0,1.0 };
    CGFloat locations[3] = {0, 0.3, 1.0};
    CGGradientRef gradient= CGGradientCreateWithColorComponents(colorSpace, compoents, locations, 3);
    
    /* 繪製線性漸變
     context:圖形上下文 
     gradient:漸變色 
     startPoint:起始位置
     endPoint:終止位置
     options:繪製方式,kCGGradientDrawsBeforeStartLocation 開始位置之前就進行繪製,到結束位置之後不再繪製, kCGGradientDrawsAfterEndLocation開始位置之前不進行繪製,到結束點之後繼續填充 */
    CGContextDrawLinearGradient(context, gradient, CGPointZero, CGPointMake(320, 300), kCGGradientDrawsBeforeStartLocation);
    //釋放顏色空間
    CGColorSpaceRelease(colorSpace);

}

#pragma mark 徑向漸變
- (void)drawRadialGradient:(CGContextRef)context {
    
    //使用rgb顏色空間
    CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
    
    /*指定漸變色 
     space:顏色空間 
     components:顏色陣列,注意由於指定了RGB顏色空間,那麼四個陣列元素表示一個顏色(red、green、blue、alpha), 如果有三個顏色則這個陣列有4*3個元素 
     locations:顏色所在位置(範圍0~1),這個陣列的個數不小於components中存放顏色的個數 
     count:漸變個數,等於locations的個數 */

    CGFloat compoents[12] = {
        248.0/255.0,86.0/255.0,86.0/255.0,1,
        249.0/255.0,127.0/255.0,127.0/255.0,1,
        1.0,1.0,1.0,1.0
    };
    
    CGFloat locations[3]={0,0.3,1.0
        };
    CGGradientRef gradient= CGGradientCreateWithColorComponents(colorSpace, compoents, locations, 3);
    
    /*繪製徑向漸變 
     context:圖形上下文
     gradient:漸變色 
     startCenter:起始點位置 
     startRadius:起始半徑(通常為0,否則在此半徑範圍內容無任何填充) 
     endCenter:終點位置(通常和起始點相同,否則會有偏移) 
     endRadius:終點半徑(也就是漸變的擴散長度) 
     options:繪製方式,kCGGradientDrawsBeforeStartLocation 開始位置之前就進行繪製,但是到結束位置之後不再繪製, kCGGradientDrawsAfterEndLocation開始位置之前不進行繪製,但到結束點之後繼續填充 */
    CGContextDrawRadialGradient(context, gradient, CGPointMake(160, 284),0, CGPointMake(165, 289), 150, kCGGradientDrawsAfterEndLocation);
    //釋放顏色空間
    CGColorSpaceRelease(colorSpace);
}

#pragma mark - 裁切矩形填充漸變色
-(void)drawRectWithLinearGradientFill:(CGContextRef)context {
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    //裁切處一塊矩形用於顯示,注意必須先裁切再呼叫漸變
    //CGContextClipToRect(context, CGRectMake(20, 50, 280, 300)); //裁切還可以使用UIKit中對應的方法
    UIRectClip(CGRectMake(20, 50, 280, 300));
    CGFloat compoents[12]={ 248.0/255.0,86.0/255.0,86.0/255.0,1, 249.0/255.0,127.0/255.0,127.0/255.0,1, 1.0,1.0,1.0,1.0 };
    CGFloat locations[3]={0,0.3,1.0};
    CGGradientRef gradient= CGGradientCreateWithColorComponents(colorSpace, compoents, locations, 3);
    CGContextDrawLinearGradient(context, gradient, CGPointMake(20, 50), CGPointMake(300, 300), kCGGradientDrawsAfterEndLocation);
    //釋放顏色空間
    CGColorSpaceRelease(colorSpace);
}

#pragma mark - 顏色疊加
/** 使用Quartz 2D繪圖時後面繪製的影象會覆蓋前面的,預設情況下如果前面的被覆蓋後將看不到後面的內容,但是有時候這個結果並不是我們想要的,因此在Quartz 2D中提供了填充模式供開發者配置調整。由於填充模式類別特別多,因此下面以一個例子來說明: */
-(void)drawRectByUIKitWithContext2:(CGContextRef)context {
    
    CGRect rect= CGRectMake(0, 130.0, 320.0, 50.0);
    CGRect rect1= CGRectMake(0, 390.0, 320.0, 50.0);
    CGRect rect2=CGRectMake(20, 50.0, 10.0, 250.0);
    CGRect rect3=CGRectMake(40.0, 50.0, 10.0, 250.0);
    CGRect rect4=CGRectMake(60.0, 50.0, 10.0, 250.0);
    CGRect rect5=CGRectMake(80.0, 50.0, 10.0, 250.0);
    CGRect rect6=CGRectMake(100.0, 50.0, 10.0, 250.0);
    CGRect rect7=CGRectMake(120.0, 50.0, 10.0, 250.0);
    CGRect rect8=CGRectMake(140.0, 50.0, 10.0, 250.0);
    CGRect rect9=CGRectMake(160.0, 50.0, 10.0, 250.0);
    CGRect rect10=CGRectMake(180.0, 50.0, 10.0, 250.0);
    CGRect rect11=CGRectMake(200.0, 50.0, 10.0, 250.0);
    CGRect rect12=CGRectMake(220.0, 50.0, 10.0, 250.0);
    CGRect rect13=CGRectMake(240.0, 50.0, 10.0, 250.0);
    CGRect rect14=CGRectMake(260.0, 50.0, 10.0, 250.0);
    CGRect rect15=CGRectMake(280.0, 50.0, 10.0, 250.0);
    CGRect rect16=CGRectMake(30.0, 310.0, 10.0, 250.0);
    CGRect rect17=CGRectMake(50.0, 310.0, 10.0, 250.0);
    CGRect rect18=CGRectMake(70.0, 310.0, 10.0, 250.0);
    CGRect rect19=CGRectMake(90.0, 310.0, 10.0, 250.0);
    CGRect rect20=CGRectMake(110.0, 310.0, 10.0, 250.0);
    CGRect rect21=CGRectMake(130.0, 310.0, 10.0, 250.0);
    CGRect rect22=CGRectMake(150.0, 310.0, 10.0, 250.0);
    CGRect rect23=CGRectMake(170.0, 310.0, 10.0, 250.0);
    CGRect rect24=CGRectMake(190.0, 310.0, 10.0, 250.0);
    CGRect rect25=CGRectMake(210.0, 310.0, 10.0, 250.0);
    CGRect rect26=CGRectMake(230.0, 310.0, 10.0, 250.0);
    CGRect rect27=CGRectMake(250.0, 310.0, 10.0, 250.0);
    CGRect rect28=CGRectMake(270.0, 310.0, 10.0, 250.0);
    CGRect rect29=CGRectMake(290.0, 310.0, 10.0, 250.0);
    
    [[UIColor yellowColor]set]; UIRectFill(rect);
    [[UIColor greenColor]setFill]; UIRectFill(rect1);
    [[UIColor redColor]setFill];
    UIRectFillUsingBlendMode(rect2, kCGBlendModeClear);
    UIRectFillUsingBlendMode(rect3, kCGBlendModeColor);
    UIRectFillUsingBlendMode(rect4, kCGBlendModeColorBurn);
    UIRectFillUsingBlendMode(rect5, kCGBlendModeColorDodge);
    UIRectFillUsingBlendMode(rect6, kCGBlendModeCopy);
    UIRectFillUsingBlendMode(rect7, kCGBlendModeDarken);
    UIRectFillUsingBlendMode(rect8, kCGBlendModeDestinationAtop);
    UIRectFillUsingBlendMode(rect9, kCGBlendModeDestinationIn);
    UIRectFillUsingBlendMode(rect10, kCGBlendModeDestinationOut);
    UIRectFillUsingBlendMode(rect11, kCGBlendModeDestinationOver);
    UIRectFillUsingBlendMode(rect12, kCGBlendModeDifference);
    UIRectFillUsingBlendMode(rect13, kCGBlendModeExclusion);
    UIRectFillUsingBlendMode(rect14, kCGBlendModeHardLight);
    UIRectFillUsingBlendMode(rect15, kCGBlendModeHue);
    UIRectFillUsingBlendMode(rect16, kCGBlendModeLighten);
    UIRectFillUsingBlendMode(rect17, kCGBlendModeLuminosity);
    UIRectFillUsingBlendMode(rect18, kCGBlendModeMultiply);
    UIRectFillUsingBlendMode(rect19, kCGBlendModeNormal);
    UIRectFillUsingBlendMode(rect20, kCGBlendModeOverlay);
    UIRectFillUsingBlendMode(rect21, kCGBlendModePlusDarker);
    UIRectFillUsingBlendMode(rect22, kCGBlendModePlusLighter);
    UIRectFillUsingBlendMode(rect23, kCGBlendModeSaturation);
    UIRectFillUsingBlendMode(rect24, kCGBlendModeScreen);
    UIRectFillUsingBlendMode(rect25, kCGBlendModeSoftLight);
    UIRectFillUsingBlendMode(rect26, kCGBlendModeSourceAtop);
    UIRectFillUsingBlendMode(rect27, kCGBlendModeSourceIn);
    UIRectFillUsingBlendMode(rect28, kCGBlendModeSourceOut);
    UIRectFillUsingBlendMode(rect29, kCGBlendModeXOR);

}

#pragma mark - 瓷磚填充

#pragma mark - 有顏色填充模式 
void drawColoredTile(void *info,CGContextRef context) {
    
    //有顏色填充,這裡設定填充色
    CGContextSetRGBFillColor(context, 254.0/255.0, 52.0/255.0, 90.0/255.0, 1);
    CGContextFillRect(context, CGRectMake(0, 0, TILE_SIZE, TILE_SIZE));
    CGContextFillRect(context, CGRectMake(TILE_SIZE, TILE_SIZE, TILE_SIZE, TILE_SIZE));
}

-(void)drawBackgroundWithColoredPattern:(CGContextRef)context {
    //裝置無關的顏色空間 //
    CGColorSpaceRef rgbSpace= CGColorSpaceCreateDeviceRGB();
    
    //模式填充顏色空間,注意對於有顏色填充模式,這裡傳NULL
    CGColorSpaceRef colorSpace=CGColorSpaceCreatePattern(NULL);
    
    //將填充色顏色空間設定為模式填充的顏色空間
    CGContextSetFillColorSpace(context, colorSpace);
    
    //填充模式回撥函式結構體
    CGPatternCallbacks callback={0,&drawColoredTile,NULL};
    
    /*填充模式 
     info://傳遞給callback的引數 
     bounds:瓷磚大小 matrix:形變
     xStep:瓷磚橫向間距
     yStep:瓷磚縱向間距
     tiling:貼磚的方法 
     isClored:繪製的瓷磚是否已經指定了顏色(對於有顏色瓷磚此處指定位true) 
     callbacks:回撥函式 
     */
    
    CGPatternRef pattern=CGPatternCreate(NULL, CGRectMake(0, 0, 2*TILE_SIZE, 2*TILE_SIZE), CGAffineTransformIdentity,2*TILE_SIZE+ 5,2*TILE_SIZE+ 5, kCGPatternTilingNoDistortion, true, &callback); CGFloat alpha=1;
    
    //注意最後一個引數對於有顏色瓷磚指定為透明度的引數地址,對於無顏色瓷磚則指定當前顏色空間對應的顏色陣列
    
    CGContextSetFillPattern(context, pattern, &alpha);
    UIRectFill(CGRectMake(0, 0, 320, 568));
    
    // CGColorSpaceRelease(rgbSpace);
    CGColorSpaceRelease(colorSpace);
    CGPatternRelease(pattern);

}

#pragma mark - 無顏色填充模式 
//填充瓷磚的回撥函式(必須滿足CGPatternCallbacks簽名)

void drawTile(void *info,CGContextRef context) {
    
    CGContextFillRect(context, CGRectMake(0, 0, TILE_SIZE, TILE_SIZE)); CGContextFillRect(context, CGRectMake(TILE_SIZE, TILE_SIZE, TILE_SIZE, TILE_SIZE));
}

- (void)drawBackgroundWithPattern:(CGContextRef)context {
    
    //裝置無關的顏色空間
    CGColorSpaceRef rgbSpace= CGColorSpaceCreateDeviceRGB();
    
    //模式填充顏色空間
    CGColorSpaceRef colorSpace=CGColorSpaceCreatePattern(rgbSpace);
    //將填充色顏色空間設定為模式填充的顏色空間
    CGContextSetFillColorSpace(context, colorSpace);
    //填充模式回撥函式結構體
    CGPatternCallbacks callback={0,&drawTile,NULL};
    
    /*填充模式 
     info://傳遞給callback的引數
     bounds:瓷磚大小 
     matrix:形變 
     xStep:瓷磚橫向間距 
     yStep:瓷磚縱向間距 
     tiling:貼磚的方法(瓷磚擺放的方式)
     isClored:繪製的瓷磚是否已經指定了顏色(對於無顏色瓷磚此處指定位false) 
     callbacks:回撥函式 */
    CGPatternRef pattern = CGPatternCreate(NULL, CGRectMake(0, 0, 2*TILE_SIZE, 2*TILE_SIZE), CGAffineTransformIdentity,2*TILE_SIZE+ 5,2*TILE_SIZE+ 5, kCGPatternTilingNoDistortion, false, &callback);
    CGFloat components[]={254.0/255.0,52.0/255.0,90.0/255.0,1.0};
    
    
    //注意最後一個引數對於無顏色填充模式指定為當前顏色空間顏色資料
    CGContextSetFillPattern(context, pattern, components);
    // CGContextSetStrokePattern(context, pattern, components);
    
    UIRectFill(CGRectMake(0, 0, 320, 568));
    CGColorSpaceRelease(rgbSpace);
    CGColorSpaceRelease(colorSpace);
    CGPatternRelease(pattern);
}

#pragma mark 圖形上下文形變 
-(void)drawImage:(CGContextRef)context {
    //儲存初始狀態
    CGContextSaveGState(context);
    
    //形變第一步:圖形上下文向右平移40
    CGContextTranslateCTM(context, 100, 0);
    
    //形變第二步:縮放0.8
    CGContextScaleCTM(context, 0.8, 0.8);
    
    //形變第三步:旋轉
    CGContextRotateCTM(context, M_PI_4/4);
    
    UIImage *image=[UIImage imageNamed:@"螢幕快照 2016-04-28 上午11.14.29"];
    [image drawInRect:CGRectMake(0, 50, 240, 300)];
    
    //恢復到初始狀態
    CGContextRestoreGState(context);

}

#pragma mark - 內建圖片繪製
-(void)drawImage2:(CGContextRef)context {
    UIImage *image = [UIImage imageNamed:@"螢幕快照 2016-04-28 上午11.14.29"];
    //影象繪製
    CGRect rect= CGRectMake(10, 50, 300, 450);
    CGContextDrawImage(context, rect, image.CGImage);
}
複製程式碼

三、濾鏡使用

#import "FilterCoreViewController.h"
#define CONSTROLPANEL_FONTSIZE 12

@interface FilterCoreViewController () <UINavigationControllerDelegate,UIImagePickerControllerDelegate> {
    UIImagePickerController *_imagePickerController;//系統照片選擇控制器
    UIImageView *_imageView;//圖片顯示控制元件
    CIContext *_context;//Core Image上下文
    CIImage *_image;//我們要編輯的影象
    CIImage *_outputImage;//處理後的影象
    CIFilter *_colorControlsFilter;//色彩濾鏡
}

@end

@implementation FilterCoreViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    [self initLayout];
    
}

#pragma mark 初始化佈局
-(void)initLayout {
    //初始化圖片選擇器
    _imagePickerController=[[UIImagePickerController alloc]init];
    _imagePickerController.delegate =self;
    
    //建立圖片顯示控制元件
    _imageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 64, 320, 502)];
    _imageView.contentMode=UIViewContentModeScaleAspectFit;
    [self.view addSubview:_imageView];
    
    //上方導航按鈕
    self.navigationItem.title = @"Enhance";
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"Open" style:UIBarButtonItemStyleDone target:self action:@selector(openPhoto:)];
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"Save" style:UIBarButtonItemStyleDone target:self action:@selector(savePhoto:)];
    
    
    //下方控制皮膚
    UIView *controlView=[[UIView alloc]initWithFrame:CGRectMake(0, 450, 320, 118)];
    //    controlView.alpha=0.2;
    //    controlView.backgroundColor=[UIColor colorWithRed:46.0/255.0 green:178.0/255.0 blue:235.0/255.0 alpha:1];
    [self.view addSubview:controlView];
    //飽和度(預設為1,大於飽和度增加小於1則降低)
    UILabel *lbSaturation=[[UILabel alloc]initWithFrame:CGRectMake(10, 10, 60, 25)];
    lbSaturation.text=@"Saturation";
    lbSaturation.font=[UIFont systemFontOfSize:CONSTROLPANEL_FONTSIZE];
    [controlView addSubview:lbSaturation];
    UISlider *sldStaturation=[[UISlider alloc]initWithFrame:CGRectMake(80, 10, 230, 30)];//注意UISlider高度雖然無法調整,很多朋友會說高度設定位0即可,事實上在iOS7中設定為0後是無法拖動的
    [controlView addSubview:sldStaturation];
    sldStaturation.minimumValue=0;
    sldStaturation.maximumValue=2;
    sldStaturation.value=1;
    [sldStaturation addTarget:self action:@selector(changeStaturation:) forControlEvents:UIControlEventValueChanged];
    //亮度(預設為0)
    UILabel *lbBrightness=[[UILabel alloc]initWithFrame:CGRectMake(10, 40, 60, 25)];
    lbBrightness.text=@"Brightness";
    lbBrightness.font=[UIFont systemFontOfSize:CONSTROLPANEL_FONTSIZE];
    [controlView addSubview:lbBrightness];
    UISlider *sldBrightness=[[UISlider alloc]initWithFrame:CGRectMake(80, 40, 230, 30)];
    [controlView addSubview:sldBrightness];
    sldBrightness.minimumValue=-1;
    sldBrightness.maximumValue=1;
    sldBrightness.value=0;
    [sldBrightness addTarget:self action:@selector(changeBrightness:) forControlEvents:UIControlEventValueChanged];
    //對比度(預設為1)
    UILabel *lbContrast=[[UILabel alloc]initWithFrame:CGRectMake(10, 70, 60, 25)];
    lbContrast.text=@"Contrast";
    lbContrast.font=[UIFont systemFontOfSize:CONSTROLPANEL_FONTSIZE];
    [controlView addSubview:lbContrast];
    UISlider *sldContrast=[[UISlider alloc]initWithFrame:CGRectMake(80, 70, 230, 30)];
    [controlView addSubview:sldContrast];
    sldContrast.minimumValue=0;
    sldContrast.maximumValue=2;
    sldContrast.value=1;
    [sldContrast addTarget:self action:@selector(changeContrast:) forControlEvents:UIControlEventValueChanged];
    
    
    //初始化CIContext
    //建立基於CPU的影象上下文
    //    NSNumber *number=[NSNumber numberWithBool:YES];
    //    NSDictionary *option=[NSDictionary dictionaryWithObject:number forKey:kCIContextUseSoftwareRenderer];
    //    _context=[CIContext contextWithOptions:option];
    _context=[CIContext contextWithOptions:nil];//使用GPU渲染,推薦,但注意GPU的CIContext無法跨應用訪問,例如直接在UIImagePickerController的完成方法中呼叫上下文處理就會自動降級為CPU渲染,所以推薦現在完成方法中儲存影象,然後在主程式中呼叫
    //    EAGLContext *eaglContext=[[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES1];
    //    _context=[CIContext contextWithEAGLContext:eaglContext];//OpenGL優化過的影象上下文
    
    //取得濾鏡
    _colorControlsFilter=[CIFilter filterWithName:@"CIColorControls"];
    
}

#pragma mark 開啟圖片選擇器
-(void)openPhoto:(UIBarButtonItem *)btn{
    //開啟圖片選擇器
    [self presentViewController:_imagePickerController animated:YES completion:nil];
}
#pragma mark 儲存圖片
-(void)savePhoto:(UIBarButtonItem *)btn{
    //儲存照片到相簿
    UIImageWriteToSavedPhotosAlbum(_imageView.image, nil, nil, nil);
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Sytem Info" message:@"Save Success!" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    [alert show];
}

#pragma mark 圖片選擇器選擇圖片代理方法
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    //關閉圖片選擇器
    [self dismissViewControllerAnimated:YES completion:nil];
    //取得選擇圖片
    UIImage *selectedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
    _imageView.image = selectedImage;
    //初始化CIImage源影象
    _image = [CIImage imageWithCGImage:selectedImage.CGImage];
    [_colorControlsFilter setValue:_image forKey:@"inputImage"];//設定濾鏡的輸入圖片
}

#pragma mark 將輸出圖片設定到UIImageView
-(void)setImage {
    CIImage *outputImage = [_colorControlsFilter outputImage];//取得輸出影象
    CGImageRef temp = [_context createCGImage:outputImage fromRect:[outputImage extent]];
    _imageView.image = [UIImage imageWithCGImage:temp];//轉化為CGImage顯示在介面中
    
    CGImageRelease(temp);//釋放CGImage物件
}

#pragma mark 調整飽和度
-(void)changeStaturation:(UISlider *)slider{
    [_colorControlsFilter setValue:[NSNumber numberWithFloat:slider.value] forKey:@"inputSaturation"];//設定濾鏡引數
    [self setImage];
}

#pragma mark 調整亮度
-(void)changeBrightness:(UISlider *)slider{
    [_colorControlsFilter setValue:[NSNumber numberWithFloat:slider.value] forKey:@"inputBrightness"];
    [self setImage];
}

#pragma mark 調整對比度
-(void)changeContrast:(UISlider *)slider{
    [_colorControlsFilter setValue:[NSNumber numberWithFloat:slider.value] forKey:@"inputContrast"];
    [self setImage];
}
複製程式碼

相關文章