Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use CustomMode clip. Get wrong image. #200

Closed
karthuszY opened this issue Sep 25, 2018 · 15 comments
Closed

Use CustomMode clip. Get wrong image. #200

karthuszY opened this issue Sep 25, 2018 · 15 comments
Assignees
Labels

Comments

@karthuszY
Copy link

karthuszY commented Sep 25, 2018

c6960693-4649-499f-afad-45eedbd24a24

I want to clip a human face.But i got this wrong shape.Last version I use get the correct image.But this time,I update the pod and update to newest version of RSKImageCropper.It's work something wrong.

826c5fbf-f61a-4711-a24a-96fe0f893993

Can u help me to see what is the question?Here is the code.Thanks.

- (CGRect)imageCropViewControllerCustomMaskRect:(RSKImageCropViewController *)controller
{
    CGSize maskSize;
    if ([controller isPortraitInterfaceOrientation]) {
        maskSize = CGSizeMake(250, 250);
//        maskSize = CGSizeMake(180, 220);
    } else {
        maskSize = CGSizeMake(220, 220);
    }
    
    CGFloat viewWidth = CGRectGetWidth(controller.view.frame);
    CGFloat viewHeight = CGRectGetHeight(controller.view.frame);
    
    CGRect maskRect = CGRectMake((viewWidth - maskSize.width) * 0.5f,
                                (viewHeight - maskSize.height) * 0.5f,
                                maskSize.width,
                                maskSize.height);
    
    return maskRect;
}

// Returns a custom path for the mask.
- (UIBezierPath *)imageCropViewControllerCustomMaskPath:(RSKImageCropViewController *)controller
{
    return [self cropPathWithRect:controller.maskRect];
}

// Returns a custom rect in which the image can be moved.
- (CGRect)imageCropViewControllerCustomMovementRect:(RSKImageCropViewController *)controller
{
    return [self cropPathWithRect:controller.maskRect].bounds;
}

- (UIBezierPath *)cropPathWithRect:(CGRect)rect
{
    UIBezierPath *path = [UIBezierPath bezierPath];

    CGPoint top_point = (CGPoint){CGRectGetMidX(rect), CGRectGetMinY(rect) + 30};
    CGPoint left_ctrl_point = (CGPoint){CGRectGetMinX(rect), CGRectGetMinY(rect) + 20};
    CGPoint right_ctrl_point = (CGPoint){CGRectGetMaxX(rect), CGRectGetMinY(rect) + 20};
    CGPoint left_bottom_point = (CGPoint){CGRectGetMinX(rect) + 45, CGRectGetMaxY(rect)*3/4 + 20};
    CGPoint right_bottom_point = (CGPoint){CGRectGetMaxX(rect) - 45, CGRectGetMaxY(rect)*3/4 + 20};
    CGPoint bottom_ctrl_point = (CGPoint){CGRectGetMidX(rect), CGRectGetMaxY(rect) + 50};
    

    [path moveToPoint:top_point];
    [path addQuadCurveToPoint:right_bottom_point controlPoint:right_ctrl_point];
    [path addQuadCurveToPoint:left_bottom_point controlPoint:bottom_ctrl_point];
    [path addQuadCurveToPoint:top_point controlPoint:left_ctrl_point];
    [path closePath];

    return path;
}
@ruslanskorb
Copy link
Owner

@Karthus1110 Which version did you use before?

@karthuszY
Copy link
Author

@ruslanskorb Im not sure. But the version is about five month ago . I import this library five month ago.

@karthuszY
Copy link
Author

@ruslanskorb The black and white effect is not due to library. The only question is clip not correct

@ruslanskorb
Copy link
Owner

@Karthus1110 Perhaps the previous version is listed in your version control system.

@ruslanskorb
Copy link
Owner

@Karthus1110 Also, could you provide the code where you are configuring the view controller.

@karthuszY
Copy link
Author

@interface ZYDIYViewController () <TZImagePickerControllerDelegate, RSKImageCropViewControllerDelegate, RSKImageCropViewControllerDataSource, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UICollectionViewDelegate, UICollectionViewDataSource>

@property (nonatomic, strong) UICollectionView *collectionView;

@property (nonatomic, strong) NSArray *dataArr;

@end

@implementation ZYDIYViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)loadSubViews
{
    [super loadSubViews];
    
    [self.collectionView registerClass:[ZYHomeCell class] forCellWithReuseIdentifier:NSStringFromClass([ZYHomeCell class])];
    
    UIButton *rightBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    rightBtn.frame = (CGRect){0, 0, 44, 44};
    [rightBtn setImageEdgeInsets:(UIEdgeInsets){0, 10, 0, -10}];
    [rightBtn setImage:[UIImage imageNamed:@"nav_album"] forState:UIControlStateNormal];
    [rightBtn addTarget:self action:@selector(pickImageAction) forControlEvents:UIControlEventTouchUpInside];
    
    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:rightBtn];
    self.navigationbar.rightItem = rightItem;
}

#pragma mark - Image
- (void)pickImageAction
{
    WeakObj(self);
    
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
        UIImagePickerController *pickerVC = [[UIImagePickerController alloc] init];
        pickerVC.delegate = self;
        pickerVC.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        [self presentViewController:pickerVC animated:YES completion:nil];
        
        return;
    }
    
    TZImagePickerController *picker = [[TZImagePickerController alloc] initWithMaxImagesCount:1 delegate:self];
    picker.allowPickingVideo = NO;
    picker.allowPickingOriginalPhoto = NO;
    picker.didFinishPickingPhotosHandle = ^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
        [weakself cropWithImage:[photos firstObject]];
    };
    [self presentViewController:picker animated:YES completion:nil];
}

- (void)cropWithImage:(UIImage *)image
{
    RSKImageCropViewController *croper = [[RSKImageCropViewController alloc] initWithImage:image
                                                                                cropMode:RSKImageCropModeCustom];
    croper.delegate = self;
    croper.dataSource = self;
    croper.applyMaskToCroppedImage = YES;
    croper.rotationEnabled = YES;
    croper.maskLayerStrokeColor = UIHexColor(0xf75000, 1);
    
    croper.moveAndScaleLabel.text = @"把脸部放入框内,双指旋转或缩放";
    croper.moveAndScaleLabel.font = kContentFont14;
    croper.chooseButton.titleLabel.font = kContentFont14;
    croper.cancelButton.titleLabel.font = kContentFont14;
    [self.navigationController pushViewController:croper animated:YES];
}

#pragma mark - ImagePicker Delegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
    UIImage *image = info[UIImagePickerControllerOriginalImage];
    [picker dismissViewControllerAnimated:YES completion:nil];
    [self cropWithImage:image];
}

#pragma mark - Croper Delegate
- (void)imageCropViewControllerDidCancelCrop:(RSKImageCropViewController *)controller
{
    [self.navigationController popViewControllerAnimated:YES];    
}

- (void)imageCropViewController:(RSKImageCropViewController *)controller didCropImage:(UIImage *)croppedImage usingCropRect:(CGRect)cropRect rotationAngle:(CGFloat)rotationAngle
{
    ZYFaceEditController *editVC = [[ZYFaceEditController alloc] init];
    editVC.image = croppedImage;
    [self.navigationController pushViewController:editVC animated:YES];
}

#pragma mark - Croper DataSource
- (CGRect)imageCropViewControllerCustomMaskRect:(RSKImageCropViewController *)controller
{
    CGSize maskSize;
    if ([controller isPortraitInterfaceOrientation]) {
//        maskSize = CGSizeMake(250, 250);
        maskSize = CGSizeMake(180, 220);
    } else {
        maskSize = CGSizeMake(220, 220);
    }
    
    CGFloat viewWidth = CGRectGetWidth(controller.view.frame);
    CGFloat viewHeight = CGRectGetHeight(controller.view.frame);
    
    CGRect maskRect = CGRectMake((viewWidth - maskSize.width) * 0.5f,
                                (viewHeight - maskSize.height) * 0.5f,
                                maskSize.width,
                                maskSize.height);
    
    return maskRect;
}

// Returns a custom path for the mask.
- (UIBezierPath *)imageCropViewControllerCustomMaskPath:(RSKImageCropViewController *)controller
{
    return [self cropPathWithRect:controller.maskRect];
}

// Returns a custom rect in which the image can be moved.
- (CGRect)imageCropViewControllerCustomMovementRect:(RSKImageCropViewController *)controller
{
    // If the image is not rotated, then the movement rect coincides with the mask rect,
    // otherwise it is calculated individually for each custom mask.
//    return controller.maskRect;
    return [self cropPathWithRect:controller.maskRect].bounds;
}

- (UIBezierPath *)cropPathWithRect:(CGRect)rect
{
    UIBezierPath *path = [UIBezierPath bezierPath];

    /* 暂时不知道为什么裁剪出来效果不对
    CGPoint top_point = (CGPoint){CGRectGetMidX(rect), CGRectGetMinY(rect) + 30};
    CGPoint bottom_point = (CGPoint){CGRectGetMidX(rect), CGRectGetMaxY(rect)};
    CGPoint left_ctrl_point = (CGPoint){CGRectGetMinX(rect), CGRectGetMinY(rect) + 20};
    CGPoint right_ctrl_point = (CGPoint){CGRectGetMaxX(rect), CGRectGetMinY(rect) + 20};
    CGPoint left_bottom_point = (CGPoint){CGRectGetMinX(rect) + 45, CGRectGetMaxY(rect)*3/4 + 20};
    CGPoint right_bottom_point = (CGPoint){CGRectGetMaxX(rect) - 45, CGRectGetMaxY(rect)*3/4 + 20};
    CGPoint bottom_ctrl_point = (CGPoint){CGRectGetMidX(rect), CGRectGetMaxY(rect) + 50};
    

    [path moveToPoint:top_point];
    [path addQuadCurveToPoint:right_bottom_point controlPoint:right_ctrl_point];
    [path addQuadCurveToPoint:left_bottom_point controlPoint:bottom_ctrl_point];
    [path addQuadCurveToPoint:top_point controlPoint:left_ctrl_point];
//    [path addQuadCurveToPoint:left_bottom_point controlPoint:left_ctrl_point];
//    [path addQuadCurveToPoint:top_point controlPoint:right_ctrl_point];
    [path closePath];
    */
    
    
    path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:rect.size.width/2 - 15];
    
    return path;
}

#pragma mark - CollectionView
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return (int)ceil(self.dataArr.count/3.f);
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 3;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    ZYHomeCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([ZYHomeCell class]) forIndexPath:indexPath];
    cell.imageName = [self.dataArr objectAtIndexSafely:indexPath.row + indexPath.section*3];
    return cell;
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    StoryMakeImageEditorViewController *editor = [[StoryMakeImageEditorViewController alloc] initWithImage:[UIImage imageNamed:[self.dataArr objectAtIndexSafely:indexPath.row + indexPath.section*3]]];
    editor.pushNav = self.navigationController;
    [self presentViewController:editor animated:YES completion:nil];
}

#pragma mark - Properties
- (UICollectionView *)collectionView
{
    if (!_collectionView) {
        
        CGFloat padding = 10.f;
        
        UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
        flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
        flowLayout.itemSize = (CGSize){(kScreenWidth - padding*4)/3.f, (kScreenWidth - padding*4)/3.f};
        flowLayout.sectionInset = UIEdgeInsetsMake(padding, 5, 0, 5);
        
        _collectionView = [[UICollectionView alloc] initWithFrame:self.contentView.bounds collectionViewLayout:flowLayout];
        _collectionView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
        _collectionView.backgroundColor = [UIColor whiteColor];
        _collectionView.delegate = self;
        _collectionView.dataSource = self;
        [self.contentView addSubview:_collectionView];
    }
    return _collectionView;
}

- (NSArray *)dataArr
{
    if (!_dataArr) {
        NSMutableArray *nameArr = [[NSMutableArray alloc] initWithCapacity:0];
        for (int i=1; i<=31; i++) {
            NSString *name = [NSString stringWithFormat:@"diy_resource%d.jpeg", i];
            [nameArr addObject:name];
        }
        _dataArr = [NSArray arrayWithArray:nameArr];
    }
    return _dataArr;
}

@end

@karthuszY
Copy link
Author

@ruslanskorb this is the code i use before.
image

@ruslanskorb
Copy link
Owner

@Karthus1110 OK, thanks. I'll take a look at this.

@ruslanskorb
Copy link
Owner

ruslanskorb commented Sep 25, 2018

@Karthus1110 You return wrong customMovementRect from [imageCropViewControllerCustomMovementRect:].

screen shot 2018-09-25 at 10 33 29

It must cover the mask rect.

You should calculate it based on rotationAngle of RSKImageCropViewController.

Below is a simplified form of calculation.

// Returns a custom rect in which the image can be moved.
- (CGRect)imageCropViewControllerCustomMovementRect:(RSKImageCropViewController *)controller
{
    CGRect cropPathBounds = [self cropPathWithRect:controller.maskRect].bounds;
    
    CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(controller.rotationAngle);
    
    CGSize movementRectSize = CGRectApplyAffineTransform(cropPathBounds, rotationTransform).size;
    CGPoint movementRectCenter = CGPointMake(CGRectGetMidX(cropPathBounds), CGRectGetMidY(cropPathBounds));
    
    CGRect movementRect = CGRectMake(movementRectCenter.x - movementRectSize.width / 2.0,
                                     movementRectCenter.y - movementRectSize.height / 2.0,
                                     movementRectSize.width,
                                     movementRectSize.height);
    
    return movementRect;
}

Or the more accurate version:

- (CGRect)imageCropViewControllerCustomMovementRect:(RSKImageCropViewController *)controller
{
    if (controller.rotationAngle == 0) {
        return controller.maskRect;
    } else {
        CGRect maskRect = controller.maskRect;
        CGFloat rotationAngle = controller.rotationAngle;
        
        CGRect movementRect = CGRectZero;
        
        movementRect.size.width = CGRectGetWidth(maskRect) * fabs(cos(rotationAngle)) + CGRectGetHeight(maskRect) * fabs(sin(rotationAngle));
        movementRect.size.height = CGRectGetHeight(maskRect) * fabs(cos(rotationAngle)) + CGRectGetWidth(maskRect) * fabs(sin(rotationAngle));
        
        movementRect.origin.x = CGRectGetMinX(maskRect) + (CGRectGetWidth(maskRect) - CGRectGetWidth(movementRect)) * 0.5f;
        movementRect.origin.y = CGRectGetMinY(maskRect) + (CGRectGetHeight(maskRect) - CGRectGetHeight(movementRect)) * 0.5f;
        
        movementRect.origin.x = floor(CGRectGetMinX(movementRect));
        movementRect.origin.y = floor(CGRectGetMinY(movementRect));
        movementRect = CGRectIntegral(movementRect);
        
        return movementRect;
    }
}

@karthuszY
Copy link
Author

Thanks very much.I will try it.@ruslanskorb

@karthuszY
Copy link
Author

It's still wrong when i not rotate the image.
I set a breakpoint in code.It's just return controller.maskRect and still clip wrong area.
462c69f0-d5bf-4eaa-be8b-49eb8bb83f67
123bdaba-ab31-4588-8e85-b9e426f7cd31

code in else doesn't excute~

- (CGRect)imageCropViewControllerCustomMovementRect:(RSKImageCropViewController *)controller
{
    if (controller.rotationAngle == 0) {
        return controller.maskRect;
    } else {
        CGRect cropPathBounds = [self cropPathWithRect:controller.maskRect].bounds;
        
        CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(controller.rotationAngle);
        
        CGSize movementRectSize = CGRectApplyAffineTransform(cropPathBounds, rotationTransform).size;
        CGPoint movementRectCenter = CGPointMake(CGRectGetMidX(cropPathBounds), CGRectGetMidY(cropPathBounds));
        
        CGRect movementRect = CGRectMake(movementRectCenter.x - movementRectSize.width / 2.0,
                                        movementRectCenter.y - movementRectSize.height / 2.0,
                                        movementRectSize.width,
                                        movementRectSize.height);
        
        return movementRect;
    }
}

@ruslanskorb
Copy link
Owner

@Karthus1110 Could you show the image you are getting in [imageCropViewController:didCropImage:usingCropRect:rotationAngle:].?

@karthuszY
Copy link
Author

I got this.Using an imageView to show this image, without any other process
99b7ec1c-192b-4aeb-b021-0fa461467e09
3e70c960-8fb7-40b5-b05a-a35ed3b311d6

@ruslanskorb
Copy link
Owner

@Karthus1110 Use preview button to show the image.

screen shot 2018-09-26 at 05 39 27

Also, could you provide the image you are trying to crop?

@karthuszY
Copy link
Author

image
image

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants