美文网首页很常OC-开发案例收集相机
iOS实现动态区域裁剪图片--支持旋转、缩放、拖动手势

iOS实现动态区域裁剪图片--支持旋转、缩放、拖动手势

作者: 大宝来巡山 | 来源:发表于2021-02-08 18:27 被阅读0次

    不多说,先上图:

    裁剪图片.gif
    源代码仓库
    https://github.com/julyNineteen/DBCropImage

    一个专门裁剪图片轻量级的轮子,简单易用,功能丰富(高自由度的参数设定、支持旋转和缩放、拖动),能满足绝大部分裁剪的需求。源代码公开,具体详细实现逻辑参数都在里面。非常支持自定义。
    目前功能:
    ✅ 支持任意角度360度的旋转;
    ✅ 高自由度的参数设定,包括裁剪区域颜色大小、裁剪宽高比等;
    ✅支持固定或者可移动的裁剪框
    ✅ 支持固定或者可移动的裁剪框
    ✅ 裁剪算法公开,轻量级,非常适合自定义为适合自己的项目

    使用非常简单,一个初始化方法搞定

           DBCropImageController *vc = [[DBCropImageController alloc] init];
            vc.lineColor = UIColor.whiteColor;//裁剪框线条眼色
            vc.isShowShaw = true;               //裁剪框线条是否显示阴影
            vc.lineWidth = 2;                        //裁剪框线条的宽度
            vc.isFixCropArea = false;       //是否固定裁剪框
            vc.widthHeightRate = 3/4.0;//设置宽高比例
            vc.cropAreaHeight = 50;      //设置最小裁剪高度
            vc.image = image;                 //传入裁剪图片
           //裁剪图片回调
            vc.clippedBlock = ^(UIImage * _Nonnull clippedImage) {
                CupedResultVC *ResultVC = [[CupedResultVC alloc] init];
                ResultVC.resultImage = clippedImage;
                ResultVC.modalPresentationStyle = 0;
                [self presentViewController:ResultVC animated:YES completion:nil];
            };
           //取消裁剪
            vc.cancelClipBlock = ^{
                [self dismissViewControllerAnimated:YES completion:nil];
            };
            vc.modalPresentationStyle = 0;
            [self presentViewController:vc animated:YES completion:nil];
    

    核心裁剪逻辑实现在这里,代码注释非常详细,适合对图片裁剪领域的学习。

    //操作UIKit上下文的操作方式是线程安全的,但你似乎无法在一个线程之外创建一个除了主程序,因为UIGraphicsBeginImageContextWithOptions“应该只在主程序中调用线程“,但仍然这样做的工作是完美的
    - (UIImage *)clipImageWithSoucreImageView:(UIImageView *)imageView{
        
        CGRect foreCropRect = self.willCropRect;
        
        CGRect soucreRect = imageView.frame;
        
        UIImage *soucreImage = imageView.image;
        
        //缩放比例
        float zoomScale = [[imageView.layer valueForKeyPath:@"transform.scale.x"] floatValue];
       
        //计算 要裁剪图片的大小
        CGSize cropSize = CGSizeMake((foreCropRect.size.width)/zoomScale, (foreCropRect.size.height)/zoomScale);
        //计算 裁剪图片的原点
        CGPoint cropViewOrigin = CGPointMake((foreCropRect.origin.x - soucreRect.origin.x)/zoomScale,
                                                (foreCropRect.origin.y - soucreRect.origin.y)/zoomScale);
        
        //向上取整
        if((NSInteger)cropSize.width % 2 == 1)
        {
            cropSize.width = ceil(cropSize.width);
        }
        if((NSInteger)cropSize.height % 2 == 1)
        {
            cropSize.height = ceil(cropSize.height);
        }
        
        float _imageScale = soucreImage.size.width / self.cropAreaWidth;
        CGFloat imgRate = KScreenWidth/self.cropAreaWidth;
        //修正偏移量 得到最终的
        CGRect CropImageRect = CGRectMake((NSInteger)(cropViewOrigin.x)*_imageScale/imgRate ,(NSInteger)( cropViewOrigin.y)*_imageScale/imgRate, (NSInteger)(cropSize.width)*_imageScale/imgRate,(NSInteger)(cropSize.height)*_imageScale/imgRate);
       
        //旋转的角度 获取绕z轴 旋转的角度 -- 也就是当前平面旋转的角度
        float rotate = [[imageView.layer valueForKeyPath:@"transform.rotation.z"] floatValue];
        NSLog(@"旋转角度 == %f",rotate * 180/M_PI );
        //根据旋转的角度得到新的图片
        UIImage *rotInputImage = [soucreImage imageRotatedByRadians:rotate];
        
        CGImageRef tmp = CGImageCreateWithImageInRect([rotInputImage CGImage], CropImageRect);
        
        UIImage *resultImage = [UIImage imageWithCGImage:tmp scale:soucreImage.scale orientation:soucreImage.imageOrientation];
        
        if (!resultImage) {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"您剪切的区域无效,请重新剪切" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
            [alert show];
            return nil;
        }
        
        CGRect imageRect = CGRectZero;
        imageRect.size = resultImage.size;
        
        UIBezierPath *cropedPath;
        //设置为YES 不透明,节省性能
        UIGraphicsBeginImageContextWithOptions(imageRect.size, YES,1);
        {
            //[[UIColor blackColor] setFill];
            UIRectFill(imageRect);
            [[UIColor whiteColor] setFill];
            //修改
            cropedPath = [UIBezierPath bezierPathWithRect:imageRect];
            [cropedPath fill];
        }
        UIImage *maskImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        //设置为YES 不透明,节省性能
        //1 裁剪尺寸原比例 设置为0或者UIScreen.mainScreen.scale 或随屏幕分辨率放大尺寸
        UIGraphicsBeginImageContextWithOptions(imageRect.size,YES,1);
        {
            CGContextClipToMask(UIGraphicsGetCurrentContext(), imageRect, maskImage.CGImage);
            [resultImage drawAtPoint:CGPointZero];
        }
        UIImage *maskResultImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        return maskResultImage;
        
    }
    

    参考链接:
    https://www.jianshu.com/p/73043c1d869a

    相关文章

      网友评论

        本文标题:iOS实现动态区域裁剪图片--支持旋转、缩放、拖动手势

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