heitorfr / ios-image-editor

iOS View Controller for image cropping. An alternative to the UIImagePickerController editor with extended features.
MIT License
602 stars 129 forks source link

Disable cutting outside the image #8

Closed jloubet closed 11 years ago

jloubet commented 11 years ago

Hello,

I'm using your library, I want that the picture don't be able to go out of the cut area.

I almost achieve this with the following modifications in the code:

The code is working but have a bug with the pitch, I would like to discuss this with you, please take a look to the code. Thanks!

For the Pan:

- (IBAction)handlePan:(UIPanGestureRecognizer*)recognizer
{
    if([self handleGestureState:recognizer.state]) {
        CGPoint translation = [recognizer translationInView:self.imageView];

        float availableXmove = self.imageView.frame.size.width - self.cropSize.width;
        float availableYmove = self.imageView.frame.size.height - self.cropSize.height;

        if ((availableXmove>0) || (availableYmove>0)){

            float availableXmoveLeft = (availableXmove / 2) - (_totalMoveX + (translation.x * self.scale));
            float availableXmoveRight = (availableXmove / 2) + (_totalMoveX + (translation.x * self.scale));
            float availableYmoveTop = (availableYmove / 2) + (_totalMoveY - (translation.y * self.scale));
            float availableYmoveButton = (availableYmove / 2) - (_totalMoveY - (translation.y * self.scale));

            if ((availableXmoveLeft>=0) && (availableXmoveRight>=0) &&
                (availableYmoveTop>=0) && (availableYmoveButton>=0)){
                //NSLog(@"puedo mover por X o Y");
                float avaliableX = ((availableXmove) / 2);

                _totalMoveX += translation.x * self.scale;

                if ((avaliableX>_totalMoveX) && ((-1*avaliableX)<_totalMoveX)){

                    CGAffineTransform transform = CGAffineTransformTranslate( self.imageView.transform, translation.x, 0);
                    self.imageView.transform = transform;

                    [recognizer setTranslation:CGPointMake(0, 0) inView:self.frameView];

                }else{
                    _totalMoveX -= translation.x * self.scale;
                }

                float avaliableY = ((availableYmove) / 2);

                _totalMoveY -= translation.y * self.scale;
                if ((avaliableY>_totalMoveY) && ((-1*avaliableY)<_totalMoveY)){

                    CGAffineTransform transform = CGAffineTransformTranslate( self.imageView.transform, 0, translation.y);
                    self.imageView.transform = transform;

                    [recognizer setTranslation:CGPointMake(0, 0) inView:self.frameView];

                }else{
                    _totalMoveY += translation.y * self.scale;
                }
            }   
        }else{
            //NSLog(@"Err");
        }   
    }
}

For the Pinch:

- (IBAction)handlePinch:(UIPinchGestureRecognizer *)recognizer
{
    if([self handleGestureState:recognizer.state]) {
        if(recognizer.state == UIGestureRecognizerStateBegan){
            self.scaleCenter = self.touchCenter;
        }

        float availableXmove = self.imageView.frame.size.width - self.cropSize.width;
        float availableYmove = self.imageView.frame.size.height - self.cropSize.height;
        availableXmove = availableXmove / 2;
        availableYmove = availableYmove / 2;
        float availableXmoveLeft   = availableXmove - _totalMoveX;
        float availableXmoveRight  = availableXmove + _totalMoveX;
        float availableYmoveTop    = availableYmove + _totalMoveY;
        float availableYmoveButton = availableYmove - _totalMoveY;

        if ((availableXmoveLeft>=0) && (availableXmoveRight>=0) &&
            (availableYmoveTop>=0) && (availableYmoveButton>=0)){
            NSLog(@"ok");

            if ( self.scale*recognizer.scale>=1){
                CGFloat deltaX = 0;//self.scaleCenter.x-self.imageView.bounds.size.width/2.0;
                CGFloat deltaY = 0;//self.scaleCenter.y-self.imageView.bounds.size.height/2.0;

                CGAffineTransform transform =  CGAffineTransformTranslate(self.imageView.transform, deltaX, deltaY);
                transform = CGAffineTransformScale(transform, recognizer.scale, recognizer.scale);
                transform = CGAffineTransformTranslate(transform, -deltaX, -deltaY);

                self.scale *= recognizer.scale;

                self.imageView.transform = transform;

                recognizer.scale = 1;
            }
        }else{
            NSLog(@"Err");
        }
    }
} 
heitorfr commented 11 years ago

Hi. I had this on my pipeline for some time now and finally implemented a 'checkBounds' setting that does what you want. Instead of blocking gestures, it will correct the transformations when gestures are finished. Rotation is not supported though. All the best.

jloubet commented 11 years ago

Heitor, thank you very much, that works great. For rotation validation I think you should use trigonometric function to make the validation. Thanks again.

heitorfr commented 11 years ago

I'll take the challenge when I have some time again ;)