天天看點

Quartz 2D 繪圖

#pragma mark - 使用預設的context繪制直線

-(void)drawLine{

    // 1. 取得上下文

    CGContextRef context = UIGraphicsGetCurrentContext();

    // 2. 起始點

    CGContextMoveToPoint(context, 50, 50);

    // 1) 起始點到第一個點

    CGContextAddLineToPoint(context, 200, 200);

    // 2) 第一個點到第二個點 如果不封閉圖形就是兩條線

    CGContextAddLineToPoint(context, 20, 200);

    // 3) 封閉圖形後就是三角形

    CGContextClosePath(context);

    // 3. 設定屬性

    // 設定邊線

    [[UIColor redColor] setStroke];

    // 設定填充

    [[UIColor blueColor] setFill];

    // 設定邊線和填充

//    [[UIColor greenColor] set];

    // 4. 繪制路徑 雖然沒有直接定義路徑,但是第2步操作,就是為上下文指定路徑

    CGContextDrawPath(context, kCGPathFillStroke);

}

#pragma mark - 使用路徑繪制直線

-(void)drawLine2{

    // 提示,使用Ref聲明的對象,不需要用*

    // 1. 擷取上下文-UIView對應的上下文

    CGContextRef context = UIGraphicsGetCurrentContext();

    // 2. 建立可變的路徑并設定路徑

    CGMutablePathRef path = CGPathCreateMutable();

    // 劃線->

    // 1) 設定起始點

    CGPathMoveToPoint(path, NULL, 50, 50);

    // 2) 設定目标點

    CGPathAddLineToPoint(path, NULL, 200, 200);

    CGPathAddLineToPoint(path, NULL, 50, 200);

    // 3) 封閉路徑

    CGPathCloseSubpath(path);

    // 3. 将路徑添加到上下文

    CGContextAddPath(context, path);

    // 4. 設定上下文屬性

    CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);

    CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 1.0);

    // 設定線條寬度

    CGContextSetLineWidth(context, 5.0);

    // 設定線條的頂點樣式

    CGContextSetLineCap(context, kCGLineCapRound);

    // 設定線條的連接配接點樣式

    CGContextSetLineJoin(context, kCGLineJoinRound);

     // 設定線條的虛線樣式

    CGFloat lengths[2] = {20.0,10.0};

    CGContextSetLineDash(context, 0.0, lengths, 2);

    // 5. 繪制路徑

    CGContextDrawPath(context, kCGPathFillStroke);

    // 6. 釋放路徑

    CGPathRelease(path);

}

#pragma mark - 繪制矩形

-(void)drawShapeRect{

    CGRect rect = CGRectMake(50, 50, 200, 200);

    [[UIColor redColor] set];

    // 繪制實心矩形

    UIRectFill(rect);

    // 繪制空心矩形

    UIRectFrame(CGRectMake(50, 300, 100, 100));

}

#pragma mark - 繪制圓形

-(void)drawShapeCycle{

    // 1. 取出上下文

    CGContextRef context = UIGraphicsGetCurrentContext();

    UIRectFrame(CGRectMake(50, 50, 200, 100));

    // 2. 設定路徑

    CGContextAddEllipseInRect(context, CGRectMake(50, 50, 200, 100));

    // 3. 繪制圓形路徑

    CGContextDrawPath(context, kCGPathFillStroke);

}

#pragma mark - 繪制圓弧

-(void)drawArc{

    // 1. 取得上下文

    CGContextRef context = UIGraphicsGetCurrentContext();

    // 2. 設定路徑

    CGContextAddArc(context, 160, 230, 100, -M_PI_4, M_PI_4, 0);

    // 3. 繪制路徑

    CGContextDrawPath(context, kCGPathStroke);

}

#pragma mark - 繪制文字  中文豎排

-(void)drawText{

    NSString * str =  @"Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world ";

    NSString * str1 = @"般若波羅蜜多心經";

    // 指定點繪制字元串

//    [str drawAtPoint:CGPointMake(50, 50) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17],NSForegroundColorAttributeName:[UIColor brownColor]}];

    // 如果在UILabel中,可以将numbersOfLine設定為0,并且指定足夠的高度即可

    [[UIColor lightGrayColor] set];

    UIRectFill(CGRectMake(8, 50, 150, 360));

     // 在指定區域繪制字元串 橫向

    [str drawInRect:CGRectMake(8, 50, 150, 360) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17],NSForegroundColorAttributeName:[UIColor brownColor]}];

    [[UIColor lightGrayColor] set];

    UIRectFill(CGRectMake(162, 50, 30, 360));

    // 中文豎排 就是讓rect的寬度窄一些  這樣字元串就垂直了

    [str1 drawInRect:CGRectMake(162, 50, 30, 360) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17],NSForegroundColorAttributeName:[UIColor brownColor]}];

}

#pragma mark - 繪制圖像

-(void)drawImage{

    UIImage * img = [UIImage imageNamed:@"頭像1.png"];

    // 提示:繪制之後,就無法改變位置,也沒有辦法監聽手勢識别

    // 在指定點繪制圖像  Point top-left corner of the image

    [img drawAtPoint:CGPointMake(50, 50)];

    // 會在指定的矩形中拉伸繪制

    [img drawInRect:CGRectMake(0, 0, 320, 460)];

    // 在指定矩形區域中平鋪圖檔

    [img drawAsPatternInRect:CGRectMake(0, 0, 320, 460)];

}

#pragma mark - 繪制五角星

分析  我們繪圖肯定是要要直線 那麼就要計算 畫一條直線所走過的圓心角 給五角星的角度編号 0 ,1 ,2, 3, 4   第一條直線應才是0 ->2 那麼它走過的角度上 2/5 *360 = 144度(從0->1 為一個内角  五個内角加起來值為360) 同理第二條第三條第四條也是的 ;  假如我們把0剛好放在y坐标正軸上(坐标是 0, r)  那麼我們可以算出2這個點的 x  y 坐标  分析的知 x = r * cos((2 * M_PI / 5.0) * 2.0 -  M_PI_2)   y = r* sin((2 * M_PI / 5.0) * 2.0 -  M_PI_2)  M_PI表示圓周率 不是表示360  角度轉換成弧度的公式 : (角度 * 2π)/ 360  是以144度  144 * M_PI/180=(4/5)* M_PI

@interface DrawFivePointStar() {

    // 是否已經計算過五角星頂點

    BOOL _hasPoint;

    // 記錄五角星的五個頂點 數組

    CGPoint points[5];

}

@end

@implementation DrawFivePointStar

#pragma mark - 記錄五角星的五個頂點

//  Only override drawRect: if you perform custom drawing.

//  An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect {  // 這裡其實隻調用了一次

    if (!_hasPoint) {  // 沒有計算過角度 第一次 初始的時候

        [self loadPoints];

        _hasPoint = YES;

    }

    static int times = 0 ;

    NSLog(@"%d",++times);

    CGContextRef context = UIGraphicsGetCurrentContext();

    [self drawRandomStarWithContext:context count:16];

}

#pragma mark - 通過第一個點 計算出五角星的五個頂點坐标

-(void)loadPoints{

   // 半徑

    CGFloat r = 100 ;

    // 第一個點的坐标是 中心點(0,0) 第一個點坐标為( 0, 0-r )

    points[0] = CGPointMake(0, -r);

    // 每畫一條直線轉過的角度 每次旋轉 (2 * M_PI / 5.0) * 2.0 = 144 度  M_PI表示圓周率 不是表示360

    CGFloat angle = (4.0/5.0) * M_PI ;

    // 計算出畫四條線每條線的坐标是

    for (int i = 1; i<5; i++) {

        // 計算出下一個點的坐标 相對的(0,0)計算的

        CGFloat x = r * cosf(i*angle - M_PI_2);

        CGFloat y = r * sinf(i*angle - M_PI_2) ;

        points[i]=CGPointMake(x, y);

    }

}

#pragma mark - 對畫的五角星進行位置 角度 大小的随機設定

-(void)drawRandomStarWithContext:(CGContextRef )context count:(NSInteger) count{

    for (NSInteger i = 0 ; i<count; i++) {

        // 儲存上下文 最初的坐标系

        CGContextSaveGState(context);

        // 下列操作會改變目前context的坐标系

        // 平移上下文

        CGFloat x = arc4random()%320;

        CGFloat y = arc4random()%480;

        CGContextTranslateCTM(context, x, y);

        // 旋轉上下文

        CGFloat angle = (arc4random()%180 * M_PI/180.0);

        CGContextRotateCTM(context, angle);

        // 縮放上下文

        CGFloat scale = arc4random_uniform(5)/10.0 + 0.5 ;

        CGContextScaleCTM(context, scale, scale);

        // 繪制五角星

        [self drawStarWithContext:context];

        // 恢複之前的上下文 最初的坐标系

        CGContextRestoreGState(context);

    }

}

#pragma mark - 對畫的五角星的顔色進行随機指派

-(UIColor *)randomColor{

    CGFloat r = arc4random_uniform(255)/255.0;

    CGFloat g = arc4random_uniform(255)/255.0;

    CGFloat b = arc4random_uniform(255)/255.0;

    return [UIColor colorWithRed:r green:g blue:b alpha:1.0];

}

#pragma mark - 繪制五角星

-(void)drawStarWithContext:(CGContextRef ) context{

    [[self randomColor] set];

    // 設定起始點

    CGContextMoveToPoint(context, points[0].x, points[0].y);

    // 設定路徑,計算其他四個點的坐标 技巧, 一個一個計算調試 否則畫太多不好調試

    for (int i = 1; i<5; i++) {

        CGContextAddLineToPoint(context, points[i].x, points[i].y);

    }

    // 關閉路徑

    CGContextClosePath(context);

    // 繪制路徑

    CGContextDrawPath(context, kCGPathFillStroke);

}

#pragma mark - 繪制線性漸變  裁剪

-(void)drawLinearGradient{

    // 在計算機中直接選RGB即可 其他的顔色空間暫時不做考慮

    // 1. 建立色彩空間上下文 注意這裡用的 create 是以後面得要release

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    // 2. 建立漸變的色彩組成

    CGFloat components[12] = {

                              1.0,0.0,0.0,1.0,

                              0.0,1.0,1.0,1.0,

                              1.0,1.0,1.0,1.0

                              };

//    CGFloat locations[3] = {0.0,0.2,1.0};

    CGFloat locations[3] = {0.2,0.0,1.0};

    // 3. 建立漸變  注意這裡用的 create 是以後面得要release

    CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 3);

    // 漸變的區域裁剪

    CGRect rects[5] = {

        CGRectMake(0, 0, 100, 100),

        CGRectMake(200, 0, 100, 100),

        CGRectMake(100, 100, 100, 100),

        CGRectMake(200, 200, 100, 100),

        CGRectMake(0, 200, 100, 100)

    };

    // 裁剪  後面畫圖能夠顯示的傳回就是裁剪出來的範圍  在圖檔裁剪上這個應用的很多  很重要 !!!

    CGContextClipToRects(UIGraphicsGetCurrentContext(), rects, 5);

    // 4. 通過上下文 繪制線性漸變

    CGContextDrawLinearGradient(UIGraphicsGetCurrentContext(), gradient, CGPointMake(0, 0), CGPointMake(320, 480), kCGGradientDrawsAfterEndLocation);

    // 5. 釋放對像

    CGColorSpaceRelease(colorSpace);

    CGGradientRelease(gradient);

}

#pragma mark - 繪制徑向漸變

-(void)drawRadialGradient{

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGFloat components[12]={

                            1.0,0.0,0.0,1.0,

                            0.0,1.0,1.0,1.0,

                            0.0,0.0,1.0,1.0

                           };

    CGFloat locations[3] = {0.0,0.6,1.0};

    // 這裡也可以裁剪區域 本處沒有裁剪

    CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 3);

    // 繪制漸變

    CGContextDrawRadialGradient(UIGraphicsGetCurrentContext(), gradient, CGPointMake(160, 240), 160, CGPointMake(160, 240), 50, kCGGradientDrawsAfterEndLocation);

    CGColorSpaceRelease(colorSpace);

    CGGradientRelease(gradient);

}

注意:以上方法都是在一個繼承自UIView的子類中操作的  也就是說 在UIViewController裡面這樣 畫圖是畫不出任何東西的(線,字元串,圖檔都畫不出來) 但是其實他的操作還是進行了 

#pragma mark - 在ViewController中  繪制圖檔水印

@interface ImageWaterMarkVC (){

    UIImageView * imgV;

}

@end

@implementation ImageWaterMarkVC

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    UIButton * btn =[[UIButton alloc] initWithFrame:CGRectMake(100, 0, 150, 50)];

    btn.backgroundColor=[UIColor lightGrayColor];

    [btn setTitle:@"給圖檔加水印" forState:UIControlStateNormal];

    [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:btn];

    UIImage * img = [UIImage imageNamed:@"NatGeo01.png"];

    imgV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 80, 320, 200)];

    imgV.image = img;

    [self.view addSubview:imgV];

}

-(void)btnClick:(UIButton*)sender{

//    UIImage * newImage = [self waterMarkImage:imgV.image WithTitle:@"FromWK"];

    UIImage * newImage = [self waterMarkImageView:imgV withTitle:@"FromWK"];

    NSLogSize(newImage.size);

    imgV.image = newImage;

}

// 使用這個方法涉及到 像素-->點-->像素 傳回的像素和原來一樣 那麼畫上的水印在@2x上會縮小一倍(1點2像素) 是以不如直接都用點來進行操作不涉及像素的問題 也就是直接用imageView自身的點數來進行操作

-(UIImage*)waterMarkImage:(UIImage*)img WithTitle:(NSString*)title{

    UIImage * newImage = nil;

   // img.size 是直接把像素點按照1:1還算成點的  後面的操作都是針對點

    CGSize imageSize = img.size;

    // 1. 建立圖像的上下文,需要指定新生成的圖像大小

    UIGraphicsBeginImageContext(imageSize);

    // 2. 選擇要顯示圖檔的類容大小  drawInRect: 最終的圖檔的大小是此Rect的大小 但是有效(有image圖像)的部分 是根據圖檔本身的大小以及圖檔相對于此Rect的 x , y 坐标 如下面的 (0,0)

    [img drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];

    // 3. 畫上要添加的水印 注意因為此處用到的是點操作

    [title drawInRect:CGRectMake(20, imageSize.height-30, imageSize.width-40, 30) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17],NSForegroundColorAttributeName:[UIColor redColor]}];

    // 4. 取得經過這樣畫圖後的新圖檔

    newImage = UIGraphicsGetImageFromCurrentImageContext();

    // 5. 關閉圖像上下文 釋放記憶體

    UIGraphicsEndImageContext();

    // 傳回的 newImage 又把點操作1:1的替換成了像素 這樣就導緻了一個問題 就是你畫上去的水印如果顯示在@2x螢幕上會縮小一倍 如果是@3x為縮小三倍

    return newImage;

}

// 直接用點數進行操作

-(UIImage*)waterMarkImageView:(UIImageView*)imgView withTitle:(NSString *)title{

    UIImage * newImage = nil;

    // 直接用需要顯示在的imageView的點來進行操作

    CGSize imageSize = imgView.frame.size;

    UIGraphicsBeginImageContext(imageSize);

    [imgView.image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];

    [title drawInRect:CGRectMake(20, imageSize.height-30, imageSize.width-40, 30) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17],NSForegroundColorAttributeName:[UIColor redColor]}];

    newImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return newImage;

}

#pragma mark 模仿備忘錄中的背景效果  背景平鋪(一行一行的平鋪)

@implementation MemoBackgroundVC

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    [self.view setBackgroundColor:[UIColor colorWithPatternImage:[self createMemoBackgroundImage]]];

}

-(UIImage*)createMemoBackgroundImage{

    UIImage * cellImage = nil;

    // 1. 圖像上下文

    UIGraphicsBeginImageContext(CGSizeMake(320, 46));

    // 2. 畫圖

    //    1) 畫背景的矩形

    [[UIColor yellowColor] set];

    UIRectFill(CGRectMake(0, 0, 320, 46));

    //    2) 畫底部的灰線

    [[UIColor lightGrayColor] set];

    UIRectFill(CGRectMake(0, 44.5, 320, 1.5));

    // 3. 取得圖檔

    cellImage = UIGraphicsGetImageFromCurrentImageContext();

    // 4. 關閉上下文  釋放記憶體

    UIGraphicsEndImageContext();

    // 5. 傳回圖像

    return cellImage;

}

@end

#pragma mark 畫PDF格式檔案

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    [self createPDFFile];

}

-(void)createPDFFile{

    // 1. 取得存儲路徑

    NSString * path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"123.PDF"];

    NSLog(@"%@",path);

    // 2. 建立PDF上下文

    UIGraphicsBeginPDFContextToFile(path, CGRectZero, NULL);

    // 3. 建立PDF内容

    for (int i =0 ; i < 6; i++) {

        // 1) 建立PDF頁面 每頁的裝載數量是有限的  此圖檔的大小為 640 × 400像素 是以在預設的頁面中隻能裝兩張圖檔

        //     每添加兩張圖檔後 需要重建立立一個頁面

        if (i%2) {

            UIGraphicsBeginPDFPage();

        }

        // 2) 将Image添加到PDF檔案

        NSString * imageName = [NSString stringWithFormat:@"NatGeo%02d",i+1];

        UIImage * img = [UIImage imageNamed:imageName];

        [img drawInRect:CGRectMake(0, (i%2)*396, 612, 396)];

    }

    // 4. 關閉PDF上下文 釋放記憶體

    UIGraphicsEndPDFContext();

}

#pragma mark 螢幕截圖

  1. + (instancetype)captureWithView:(UIView *)view  
  2. {  
  3.     // 1.開啟上下文  
  4.     UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0);  
  5.     // 2.将控制器view的layer渲染到上下文  
  6.     [view.layer renderInContext:UIGraphicsGetCurrentContext()];  
  7.     // 3.取出圖檔  
  8.     UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();  
  9.     // 4.結束上下文  
  10.     UIGraphicsEndImageContext();  
  11.     return newImage;  

如果一個繼承自UIView的MyView 顯示在了ViewController中   MyView包含了一個 畫上去的字元串  需要在ViewController中來改變MyView顯示(這個畫上去的字元串)的内容和字型大小 那麼 

1. MyView需要有連個屬性 一個是字元串 另一個是字元串大小  

2. 需要重寫MyView的這兩個屬性的set方法 在方法裡加上 [self setNeedsDisplay]; 這個方法的調用 來實時的重新整理MyView的顯示

CGBitmapContextCreate函數參數詳解

函數原型:

CGContextRef CGBitmapContextCreate (

   void *data,      指向要渲染的繪制記憶體的位址                         

   size_t width,   bitmap的寬度,機關為像素

   size_t height,  bitmap的高度,機關為像素

   size_t bitsPerComponent,            記憶體中像素的每個元件的位數.例如,對于32位像素格式和RGB 顔色空間,你應該将這個值設為8

   size_t bytesPerRow,                     bitmap的每一行在記憶體所占的位元組數

   CGColorSpaceRef colorspace,     bitmap上下文使用的顔色空間

   CGBitmapInfo bitmapInfo              指定bitmap是否包含alpha通道,像素中alpha通道的相對位置,像素元件是整形還是浮點型等資訊的字元串。

)

描述:建立一個位圖的上下文  此上下文向一個位圖繪制圖像  該位圖的寬高是以像素為機關的   

      每個像素的元件個數是通過space來指定的 當然space可能也指定了一個目标顔色的配置檔案   

      每個像素的每個元件的位數是通過 bitsPerComponent 來指定的    

      每個像素的位元組數 = (每個像素的每個元件的位數   * 每個像素的元件的個數 +7 )/ 8     (一個位元組一般是八位)    

      位圖的每一行由 bytesPerRow個位元組組成  且 bytesPerRow >=  width * 每個像素的位元組數  此外 bytesPerRow 必須是每個 像素位元組數的整數倍    

  data 如果不為空  那麼他指向的記憶體塊至少是  bytesPerRow * 高度個位元組    

                        如果為空 上下文的位元組數空間将會自動被建立和銷毀  并且 bytesPerRow 應該傳遞參數0來讓系統自動計算記憶體空間

     bitmapInfo 位圖資訊 指定是否本位圖應該包含一個透明圖的通道以及他是如和     生成的 還有就是元件是浮點型還是整型

位圖: 是由像素組成要有足夠多的不同色彩的像素,就可以制作出色彩豐富的圖象,逼真地表現自然界的景象,縮放和旋轉容易失真,同時檔案容

    量較大, 位圖顔色的編碼有 RGB(螢幕顯示) CMYK等  其圖像屬性有  索引顔色/顔色表 Alpha通道 色彩深度 

矢量圖像:是由數學向量組成檔案容量較小,在進行放大、縮小或旋轉等操作時圖象不會失真,不易制作色彩變化太多的圖象)

當你調用這個函數的時候,Quartz建立一個位圖繪制環境,也就是位圖上下文。當你向上下文中繪制資訊時,Quartz把你要繪制的資訊作為位圖資料繪制到指定的記憶體塊。一個新的位圖上下文的像素格式由三個參數決定:每個元件的位數,顔色空間,alpha選項。alpha值決定了繪制像素的透明性

  1. 在 iOS7以前,是使用如下方法建立的:  
  2. CG_EXTERN CGContextRef CGBitmapContextCreate(voidvoid *data, size_t width,  
  3.   size_t height, size_t bitsPerComponent, size_t bytesPerRow,  
  4.   CGColorSpaceRef space,CGImageAlphaInfo bitmapInfo)  

注意最後一個參數類型是 CGImageAlphaInfo 枚舉類型中的kCGImageAlphaPremultipliedLast值。其整型值為1

  1. typedef CF_ENUM(uint32_t, CGImageAlphaInfo)   
  2. {  
  3.   kCGImageAlphaNone,                 
  4.   kCGImageAlphaPremultipliedLast,    
  5.   kCGImageAlphaPremultipliedFirst,   
  6.   kCGImageAlphaLast,                 
  7.   kCGImageAlphaFirst,                
  8.   kCGImageAlphaNoneSkipLast,         
  9.   kCGImageAlphaNoneSkipFirst,        
  10.   kCGImageAlphaOnly                  
  11. };
  1. 但是在iOS7版本中,這個最後的參會類型發生了變化。看一下定義:  
  2. CGContextRef CGBitmapContextCreate(voidvoid *data, size_t width,  
  3.   size_t height, size_t bitsPerComponent, size_t bytesPerRow,  
  4.   CGColorSpaceRef space, CGBitmapInfo bitmapInfo)  
  5. 很明顯最後一個參數由CGImageAlphaInfo 變化為 CGBitmapInfo,看一下這個類型的定義 
  1. typedef CF_OPTIONS(uint32_t, CGBitmapInfo)  
  2.  {  
  3.   kCGBitmapAlphaInfoMask = 0x1F,  
  4.   kCGBitmapFloatComponents = (1 << 8),  
  5.   kCGBitmapByteOrderMask = 0x7000,  
  6.   kCGBitmapByteOrderDefault = (0 << 12),  
  7.   kCGBitmapByteOrder16Little = (1 << 12),  
  8.   kCGBitmapByteOrder32Little = (2 << 12),  
  9.   kCGBitmapByteOrder16Big = (3 << 12),  
  10.   kCGBitmapByteOrder32Big = (4 << 12)    
  11. } CF_ENUM_AVAILABLE(10_4, 2_0);  
  12. 從頭到尾沒有發現值為1的枚舉量值。故在使用的時候會出現如下警告: 

Implicit conversion from enumeration type 'enum CGImageAlphaInfo' to different enumeration type 'CGBitmapInfo' (aka 'enum CGBitmapInfo')  

  1. 意思很明顯不過,類型不比對非法。  
  2. 以下給出解決方法: 

  第一種方法,定義宏: 

   #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1  

  1.      #define kCGImageAlphaPremultipliedLast  (kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast)  
  2.    #else   
  3.      #define kCGImageAlphaPremultipliedLast  kCGImageAlphaPremultipliedLast  
  4.    #endif  

這樣就會直接映射出一個值為1的宏,原有方法不用改變

  1.  第二種方法:原理和第一個一樣,目的 還是為了生産出一個為1的值,直接修改代碼。  
  2.    #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1  
  3.          int bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;  
  4.    #else  
  5.          int bitmapInfo = kCGImageAlphaPremultipliedLast;  
  6.    #endif    
  7.     CGContextRef context = CGBitmapContextCreate(nil, CGContexWith*2, 290.0*2, 8, 4*CGContexWith*2, colorSpace, bitmapInfo);  
  8. 其實所有的做法,不外乎為了使這裡的值為1,類型比對。你也直接可以傳1,不用麻煩的各種寫代碼。也可以直接進行類型強制轉換,這個你随便。隻是每個人的習慣不一樣,故,如何解決,自己參考決定 。

繼續閱讀