Cropping an Image to the shape of an Overlay - iOS

前端 未结 3 548
悲哀的现实
悲哀的现实 2021-02-14 17:27

I\'m adding the overlay using pickerController\'s view and the uinavigationcontrollerdelegate as below.

-(void)navigationController:(UINavigationController *)nav         


        
相关标签:
3条回答
  • 2021-02-14 17:34

    Found this blog post entry very interesting, neat and simple to follow by Nimit Parekh.

    Following code is copy/paste into your “viewcontroller.h” file:

    #import <UIKit/UIKit.h>
    
    @interface UIImagePickerDemoViewController : UIViewController< UIImagePickerControllerDelegate, UINavigationControllerDelegate>
    
    @property(nonatomic,retain) UIImagePickerController *imgPicker;
    @property(nonatomic,retain) IBOutlet UIImageView *image_view;
    
    //- (UIImage*)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)rect;
    - (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage;
    @end
    

    Following Code copy/paste into “viewcontroller.m” file:

    // Following method is use for the mask the image.
    
    - (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
    
        CGImageRef maskRef = maskImage.CGImage; 
    
        CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                            CGImageGetHeight(maskRef),
                                            CGImageGetBitsPerComponent(maskRef),
                                            CGImageGetBitsPerPixel(maskRef),
                                            CGImageGetBytesPerRow(maskRef),
                                            CGImageGetDataProvider(maskRef), NULL, false);
    
        CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
        return [UIImage imageWithCGImage:masked];
    }
    
    // Following method is use for Cropping the image for a perticular size.
    
    - (UIImage*)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)rect
    {
        UIGraphicsBeginImageContext(rect.size);
        CGContextRef currentContext = UIGraphicsGetCurrentContext();
    
        CGContextTranslateCTM(currentContext, 0.0, rect.size.height);
        CGContextScaleCTM(currentContext, 1.0, -1.0);   
    
        CGRect clippedRect = CGRectMake(0, 0, rect.size.width, rect.size.height);
        CGContextClipToRect( currentContext, clippedRect);
        CGRect drawRect = CGRectMake(rect.origin.x * -1,rect.origin.y * -1,imageToCrop.size.width,imageToCrop.size.height);
        CGContextDrawImage(currentContext, drawRect, imageToCrop.CGImage);
        CGContextScaleCTM(currentContext, 1.0, -1.0);
    
        UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return cropped;
    }
    
    // Calling the method of maskimage.
    
    //=============================Camera Enable(display)============================================
    -(IBAction)next:(id)sender{
    
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
            self.imgPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
        }
        [self presentModalViewController:self.imgPicker animated:YES];
    }
    
    -(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
        [picker dismissModalViewControllerAnimated:YES];
    }
    
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
        [picker dismissModalViewControllerAnimated:YES];
        UIImage *img =  [info objectForKey:@"UIImagePickerControllerOriginalImage"];
            self.image_view.image=[self maskImage:img withMask:[UIImage imageNamed:@"frame.png"]];
    }
    //===============================================================================================
    
    // Calling the method of cropping the image.
    
    //=============================Camera Enable(display)============================================
    -(IBAction)next:(id)sender{
    
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
            self.imgPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
        }
        [self presentModalViewController:self.imgPicker animated:YES];
    }
    
    -(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
        [picker dismissModalViewControllerAnimated:YES];
    }
    
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
        [picker dismissModalViewControllerAnimated:YES];
        UIImage *img =  [info objectForKey:@"UIImagePickerControllerOriginalImage"];
        self.image_view.image = [self imageByCropping:img toRect:CGRectMake(0, 0, 420, 40)];
    }
    //===============================================================================================
    

    Output:

    iPhone output

    Grab the source code here.

    0 讨论(0)
  • 2021-02-14 17:36

    Im having exactly the same profile image picker controller as your. Here is my code from delegate. I don't think you need everything but you can find some useful information here

    -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
    {
        NSString *mediaType = info[UIImagePickerControllerMediaType];
    
        if([mediaType isEqualToString:(NSString *) kUTTypeImage]) {
    
            UIImage *image = info[UIImagePickerControllerOriginalImage];
            UIImage *editedImage = (UIImage *) [info objectForKey:UIImagePickerControllerEditedImage];
            CGRect croppingRect = [info[UIImagePickerControllerCropRect] CGRectValue];
    
            if (editedImage) {
                image = editedImage;
            } else {
                CGFloat smaller = 1;
                if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
                    smaller = 0.9;
                }
    
                CGFloat width = MIN(image.size.width * smaller, image.size.height * (smaller * 0.95));
                croppingRect = CGRectMake(0 + (image.size.width - width) / 2,
                                          0 + (image.size.height - width) / 2,
                                          width, width);
            }
    
            UIImage *finalImage = nil;
            if (editedImage) {
                finalImage = [UIImage image:editedImage byScalingAndCroppingForSize:kCroppedImageSize];
            } else {
                finalImage = [UIImage image:image byScalingAndCroppingForSize:kCroppedImageSize];
            }
    
            if ([self.imagePickerDelegate respondsToSelector:@selector(profileImagePicker:didSelectImage:)]) {
                [self.imagePickerDelegate profileImagePicker:self didSelectImage:finalImage];
            } else {
                NSAssert(nil, @"Delegate should confirm ProfileImagePickerControllerDelegate protocol");
            }
    
        } else if ([mediaType isEqualToString:(NSString *) kUTTypeVideo]) {
            NSAssert(nil, @"Movie is not supported");
        }
    }
    
    0 讨论(0)
  • 2021-02-14 17:59

    the short answer to your question addClip , but you mention you're a beginner, so here's all the steps from A to Z!!

    Firstly, try this category, see if it helps. (If you're not familiar w/ categories have a google or just ask here in a comment.)

    -(UIImage *)doMask
        {
        UIImage *maskImage = [UIImage imageNamed:@"yourMask.png"];
        
        CGImageRef maskRef = maskImage.CGImage;
        
        CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
            CGImageGetHeight(maskRef),
            CGImageGetBitsPerComponent(maskRef),
            CGImageGetBitsPerPixel(maskRef),
            CGImageGetBytesPerRow(maskRef),
            CGImageGetDataProvider(maskRef), NULL, false);
        
        CGImageRef maskedImageRef = CGImageCreateWithMask([self CGImage], mask);
        UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef];
        
        CGImageRelease(mask);
        CGImageRelease(maskedImageRef);
        
        return maskedImage;
        }
    

    just create (I mean in photoshop) a png mask, and get familiar with that process.

    I encourage you to master that process first...

    Here are critical categories that will help...

    -(UIImage *)becomeSquare
        {
        CGSize imageSize = self.size;
        CGFloat width = imageSize.width;
        CGFloat height = imageSize.height;
        
        UIImage *result = self;
        
        if (width != height)
            {
            CGFloat newDimension = MIN(width, height);
            CGFloat widthOffset = (width - newDimension) / 2;
            CGFloat heightOffset = (height - newDimension) / 2;
            
            UIGraphicsBeginImageContextWithOptions(
                CGSizeMake(newDimension, newDimension), NO, 0. );
            
            [result drawAtPoint:CGPointMake(-widthOffset, -heightOffset)
                blendMode:kCGBlendModeCopy alpha:1. ];
            result = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
            }
        
        return result;
        }
    

    and a couple more ...

    -(UIImage *)doScale
        {
        UIImage *result = self;
        
        CGSize size = CGSizeMake(320,320);
        UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);
        [result drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)];
        result = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return result;
        }
    
    -(UIImage *)scaled640AnyShape
        {
        if ( self.size.height < 5.0 ) return nil;
        if ( self.size.width < 5.0 ) return nil;
        
        UIImage *result = self;
        
        float widthShouldBe = 640.0;
        float heightShouldBe = widthShouldBe * ( self.size.height / self.size.width );
        
        CGSize size = CGSizeMake( widthShouldBe ,heightShouldBe );
        
        UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);
        [result drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)];
        result = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return result;
        }
    

    (obviously change the hard-coded output sizes as you wish.)

    Note that your final result, will be achieved, by a combination in the appropriate order, such as:

    yourImage = [yourImage doSquare];
    yourImage = [yourImage doMask];
    

    once you've got that working ...

    Then ....

    for LITERALLY what you ask, there are many example codes about .. e.g., what about https://stackoverflow.com/a/13870097/294884

    As you can see, you fundamentally...

    UIGraphicsBeginImageContextWithOptions(...);
    UIBezierPath * path = [UIBezierPath
        bezierPathWithRoundedRect:imageRect cornerRadius:10.f];
    [path addClip];
    [yourImage drawInRect:imageRect];
    ... then ... UIGraphicsGetImageFromCurrentImageContext();
    .. see the extensive code above for how to save it and so on.
    

    You just have to get the zoom right with the scaling examples above.

    Also note this, when you are changing the "area cropped"... https://stackoverflow.com/a/17884863/294884

    here's an example of that critical technique...

    -(UIImage *)squareAndSmall
        {
        // genius credits: https://stackoverflow.com/a/17884863/294884
        
        CGSize finalsize = CGSizeMake(640,640);
        
        CGFloat scale = MAX(
            finalsize.width/self.size.width,
            finalsize.height/self.size.height);
        CGFloat width = self.size.width * scale;
        CGFloat height = self.size.height * scale;
        
        // for example, the central area....
        CGRect imageRect = CGRectMake(
                      (finalsize.width - width)/2.0f,
                      (finalsize.height - height)/2.0f,
                      width, height);
        
        // or, the top area... CGRect imageRect = CGRectMake( 0, 0, width, height);
        
        UIGraphicsBeginImageContextWithOptions(finalsize, NO, 0);
        [self drawInRect:imageRect];
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
        UIGraphicsEndImageContext();
        return newImage;
        }
    

    Hope it all helps!

    0 讨论(0)
提交回复
热议问题