美文网首页iOS精品文章
iOS-图片裁剪技巧

iOS-图片裁剪技巧

作者: Haer不变 | 来源:发表于2017-03-14 15:02 被阅读252次

    先贴一个案例,我们做类似的图片展示的时候,都会需要对相应的图片进行裁剪以适应我们现实的大小,不然图片就会被拉伸或者压缩。

    C33F7F1A-22C3-44B6-BF2B-1D2ACE6DC076.png

    不知大家有类似需求时会怎么处理,之前我一直是获取到图片数据,然后对图片裁剪到与视图框相应的比例,然后在展示。贴上代码:

    
    UIImage * image = (UIImage*)info[UIImagePickerControllerOriginalImage];
    CGFloat scale = MIN(image.size.height / 124.0f, image.size.width / 124.0f);
    UIImage *cropImage = [image cropToSize:CGSizeMake(124 * scale, 124 * scale) usingMode:NYXCropModeCenter];
    
    

    我们需要显示图片时,第一时间会考虑到用 UIImageView这个类来实现,然而,在iOS中,UIView这个类本身就自带类似功能的实现,相比上一种方法感觉更简单快捷。

    contents属性

    CALayer 有一个属性叫做contents,这个属性的类型被定义为id,意味着它可以是任何类型的对象。在这种情况下,你可以给contents属性赋任何值,你的app仍然能够编译通过。但是,在实践中,如果你给contents赋的不是CGImage,那么你得到的图层将是空白的。

    contents这个奇怪的表现是由Mac OS的历史原因造成的。它之所以被定义为id类型,是因为在Mac OS系统上,这个属性对CGImageNSImage类型的值都起作用。如果你试图在iOS平台上将UIImage的值赋给它,只能得到一个空白的图层。一些初识Core Animation的iOS开发者可能会对这个感到困惑。

    头疼的不仅仅是我们刚才提到的这个问题。事实上,你真正要赋值的类型应该是CGImageRef,它是一个指向CGImage结构的指针。UIImage有一个CGImage属性,它返回一个CGImageRef,如果你想把这个值直接赋值给CALayercontents,那你将会得到一个编译错误。因为CGImageRef并不是一个真正的Cocoa对象,而是一个Core Foundation类型。

    尽管Core Foundation类型跟Cocoa对象在运行时貌似很像(被称作toll-free bridging),他们并不是类型兼容的,不过你可以通过bridged关键字转换。如果要给图层的寄宿图赋值,你可以按照以下这个方法

    layer.contents = (__bridge id)image.CGImage;
    

    maskToBounds

    默认情况下,UIView仍然会绘制超过边界的内容或是子视图,在CALayer下也是这样的。

    UIView有一个叫做clipsToBounds的属性可以用来决定是否显示超出边界的内容,CALayer对应的属性叫做masksToBounds

    contentsRect

    CALayercontentsRect属性允许我们在图层边框里显示寄宿图的一个子域。这涉及到图片是如何显示和拉伸的,所以要比contentsGravity灵活多了

    boundsframe不同,contentsRect不是按点来计算的,它使用了单位坐标,单位坐标指定在0到1之间,是一个相对值(像素和点就是绝对值)。所以他们是相对与寄宿图的尺寸的。

    结论

    利用以上三个layer的属性,我们就可以快速实现对示图片裁剪,贴上代码:

    int width = pic.bmiddle.width;
    
    int height = pic.bmiddle.height;
    
    CGFloat scale = (height / width) / (imageView.height / imageView.width);
    
    if (scale < 0.99 || isnan(scale)) {
    
     // 宽图把左右两边裁掉
    
    imageView.contentMode = UIViewContentModeScaleAspectFill;
    
    imageView.layer.contentsRect = CGRectMake(0, 0, 1, 1);
    
    } else {
    
     // 高图只保留顶部
    
    imageView.contentMode = UIViewContentModeScaleToFill;
    
    imageView.layer.contentsRect = CGRectMake(0, 0, 1, (float)width / height);
    
    }
    

    这样,我们就可以根据图片的宽高比例,进行适当裁剪,达到我们所需的显示效果。

    相关文章

      网友评论

        本文标题:iOS-图片裁剪技巧

        本文链接:https://www.haomeiwen.com/subject/rrchnttx.html