ios中常用的裁剪图片方法小结

一、使用Quartaz2d的画图功能裁剪。

1.例如截取图片上的一个圆:

- (UIImage *)cutCircleBg
{
    UIImage *baseImage = [UIImage imageNamed:@"LuckyBaseBackground"];
   
    // Quartz2D
    // 核心对象:上下文(保存图片)
    // 1.开始上下文(NO == 透明, 0.0 == 默认做法)
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);
   
    // 2.获得当前上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
   
    // 3.绘图裁剪
    // 3.1.画圆
    CGFloat innerCircleXY = 9;
    CGFloat innerCircleWH = ILCircleWH - innerCircleXY * 2;
    CGRect innerCircleRect = CGRectMake(innerCircleXY, innerCircleXY, innerCircleWH, innerCircleWH);
    CGContextAddEllipseInRect(ctx, innerCircleRect);
   
    // 3.2.裁剪(CGContextClip会把之前所画的剪下来)
    CGContextClip(ctx);
   
    // 3.3.画图片(这句代替后面的两句,可以免去坐标系转换的操作)
    [baseImage drawInRect:self.bounds];
//    CGContextDrawImage(ctx, self.bounds, baseImage.CGImage);
//    CGContextTranslateCTM(<#CGContextRef c#>, <#CGFloat tx#>, <#CGFloat ty#>)
   
    // 4.获得上下文中最终的图片
    UIImage *newBaseBg = UIGraphicsGetImageFromCurrentImageContext();
   
    // 5.结束上下文
    UIGraphicsEndImageContext();
   
    return newBaseBg;
}

 

2.通过重写继承于UIView的类的drawRect:方法获取当前Quartz2d的上下文来截取图片并且设置为背景

 

- (void)drawRect:(CGRect)rect
{
    // 1.画最底部的背景图
//    [[self cutCircleBg] drawInRect:rect];
    CGContextRef ctx = UIGraphicsGetCurrentContext();
   
    // copy一个ctx对象到栈中
    CGContextSaveGState(ctx);
   
    // 2.绘图裁剪
    // 2.1.画圆
    CGFloat innerCircleXY = 9;
    CGFloat innerCircleWH = ILCircleWH - innerCircleXY * 2;
    CGRect innerCircleRect = CGRectMake(innerCircleXY, innerCircleXY, innerCircleWH, innerCircleWH);
    CGContextAddEllipseInRect(ctx, innerCircleRect);
   
    // 3.2.裁剪(CGContextClip会把之前所画的剪下来)
    CGContextClip(ctx);
    [[UIImage imageNamed:@"LuckyBaseBackground"] drawInRect:rect];
  

  //取出栈中的ctx
    CGContextRestoreGState(ctx);
    
    // 4.画中间的转盘图
    [[UIImage imageNamed:@"LuckyRotateWheel"] drawInRect:rect];
   
//    [[UIColor redColor] set];
//    NSString *str = @"这是一个转盘";
//    [str drawAtPoint:CGPointZero withFont:[UIFont systemFontOfSize:30]];
}

 

这个方法中需要特别注意的是copy一个ctx对象到栈中这个操作,如果不执行这一步而是直接使用同一个ctx来画图,会因为这个ctx有裁剪功能的而使第二张图片也会裁剪后才画在这个view上,从而形成下面这种状态:

显然上面那张图片的尖角被裁剪了,而先将一个上下文ctx保存到栈中,之后再取出画第二张图片,则能达到想要的效果:

 

二、利用CGImageCreateWithImageInRect:方法裁剪,他返回一个CGImageRef对象

例如下面这个方法是将这张大图片

裁剪成12张同等大小的矩形图片

- (void)setBg:(NSString *)normal selected:(NSString *)selected
{
    for (int i = 0; i<12; i++) {
        ILCircleItemView *btn = self.subviews[i];
       
        // 加载大图片
        UIImage *normalBig = [UIImage imageNamed:normal];
       
        // 裁剪小图片
        CGFloat miniW = normalBig.size.width / 12 * [UIScreen mainScreen].scale;
        CGFloat miniH = normalBig.size.height * [UIScreen mainScreen].scale;
        CGRect miniRect = CGRectMake(i * miniW, 0, miniW, miniH);
       
        CGImageRef miniNormalCG = CGImageCreateWithImageInRect(normalBig.CGImage, miniRect);
        [btn setImage:[UIImage imageWithCGImage:miniNormalCG] forState:UIControlStateNormal];
       
        UIImage *selectedBig = [UIImage imageNamed:selected];
        CGImageRef miniSelectedCG = CGImageCreateWithImageInRect(selectedBig.CGImage, miniRect);
        [btn setImage:[UIImage imageWithCGImage:miniSelectedCG] forState:UIControlStateSelected];
    }
}

,

这里需要特别说明的是,在IOS中,所有的UI开头的类使用的都是点坐标系,例如点{480,46}在非视网膜屏幕下的像数是480*46,而在视网膜屏(retina)下的像数是960*92,所以CGFloat miniW = normalBig.size.width / 12 * [UIScreen mainScreen].scale;的作用就是区分视网膜屏([UIScreen mainScreen].scale的值是2.0)和非视网膜屏([UIScreen mainScreen].scale的值是1.0)的状况,

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值