Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ruslanskorb/RSKImageCropper

An image cropper / photo cropper for iOS like in the Contacts app with support for landscape orientation.
https://github.com/ruslanskorb/RSKImageCropper

contacts-app crop cropper cropping edit editor image photo trimming

Last synced: 6 days ago
JSON representation

An image cropper / photo cropper for iOS like in the Contacts app with support for landscape orientation.

Awesome Lists containing this project

README

        

## RSKImageCropper ![CI](https://github.com/ruslanskorb/RSKImageCropper/actions/workflows/main.yml/badge.svg) ![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-compatible-orange?style=flat) ![CocoaPods](https://img.shields.io/cocoapods/v/RSKImageCropper.svg?style=flat) ![Carthage](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)


Sample

An image cropper for iOS like in the Contacts app with support for landscape orientation.

## Installation
*RSKImageCropper requires iOS 12.0 or later.*

### Using [Swift Package Manager](https://swift.org/package-manager/)

1. To add the `RSKImageCropper` package to your Xcode project, select File > Swift Packages > Add Package Dependency and enter the repository URL.

https://github.com/ruslanskorb/RSKImageCropper.git

### Using [CocoaPods](http://cocoapods.org)

1. Add the pod `RSKImageCropper` to your [Podfile](http://guides.cocoapods.org/using/the-podfile.html).

pod 'RSKImageCropper'

2. Run `pod install` from Terminal, then open your app's `.xcworkspace` file to launch Xcode.
3. Import the `RSKImageCropper.h` header. Typically, this should be written as `#import `

### Using [Carthage](https://github.com/Carthage/Carthage)

1. Add the `ruslanskorb/RSKImageCropper` project to your [Cartfile](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md#cartfile).

github "ruslanskorb/RSKImageCropper"

2. Run `carthage update`, then follow the [additional steps required](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) to add the iOS and/or Mac frameworks into your project.
3. Import the RSKImageCropper framework/module.
* Using Modules: `@import RSKImageCropper`
* Without Modules: `#import `

## Basic Usage

Import the class header.

``` objective-c
#import
```

Just create a view controller for image cropping and set the delegate.

``` objective-c
- (IBAction)onButtonTouch:(UIButton *)sender
{
UIImage *image = [UIImage imageNamed:@"image"];
RSKImageCropViewController *imageCropViewController = [[RSKImageCropViewController alloc] initWithImage:image];
imageCropViewController.delegate = self;
[self.navigationController pushViewController:imageCropViewController animated:YES];
}
```

## Delegate

`RSKImageCropViewControllerDelegate` provides three delegate methods. To use them, implement the delegate in your view controller.

```objective-c
@interface ViewController ()
```

Then implement the delegate functions.

```objective-c
// Crop image has been canceled.
- (void)imageCropViewControllerDidCancelCrop:(RSKImageCropViewController *)controller
{
[self.navigationController popViewControllerAnimated:YES];
}

// The original image has been cropped. Additionally provides a rotation angle used to produce image.
- (void)imageCropViewController:(RSKImageCropViewController *)controller
didCropImage:(UIImage *)croppedImage
usingCropRect:(CGRect)cropRect
rotationAngle:(CGFloat)rotationAngle
{
self.imageView.image = croppedImage;
[self.navigationController popViewControllerAnimated:YES];
}

// The original image will be cropped.
- (void)imageCropViewController:(RSKImageCropViewController *)controller
willCropImage:(UIImage *)originalImage
{
// Use when `applyMaskToCroppedImage` set to YES.
[SVProgressHUD show];
}
```

## DataSource

`RSKImageCropViewControllerDataSource` provides three data source methods. The method `imageCropViewControllerCustomMaskRect:` asks the data source for a custom rect for the mask. The method `imageCropViewControllerCustomMaskPath:` asks the data source for a custom path for the mask. The method `imageCropViewControllerCustomMovementRect:` asks the data source for a custom rect in which the image can be moved. To use them, implement the data source in your view controller.

```objective-c
@interface ViewController ()
```

Then implement the data source functions.

```objective-c
// Returns a custom rect for the mask.
- (CGRect)imageCropViewControllerCustomMaskRect:(RSKImageCropViewController *)controller
{
CGSize aspectRatio = CGSizeMake(16.0f, 9.0f);

CGFloat viewWidth = CGRectGetWidth(controller.view.frame);
CGFloat viewHeight = CGRectGetHeight(controller.view.frame);

CGFloat maskWidth;
if ([controller isPortraitInterfaceOrientation]) {
maskWidth = viewWidth;
} else {
maskWidth = viewHeight;
}

CGFloat maskHeight;
do {
maskHeight = maskWidth * aspectRatio.height / aspectRatio.width;
maskWidth -= 1.0f;
} while (maskHeight != floor(maskHeight));
maskWidth += 1.0f;

CGSize maskSize = CGSizeMake(maskWidth, maskHeight);

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
{
CGRect rect = controller.maskRect;
CGPoint point1 = CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect));
CGPoint point2 = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect));
CGPoint point3 = CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect));
CGPoint point4 = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect));

UIBezierPath *rectangle = [UIBezierPath bezierPath];
[rectangle moveToPoint:point1];
[rectangle addLineToPoint:point2];
[rectangle addLineToPoint:point3];
[rectangle addLineToPoint:point4];
[rectangle closePath];

return rectangle;
}

// Returns a custom rect in which the image can be moved.
- (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;
}
}
```

## Coming Soon

- If you would like to request a new feature, feel free to raise an issue.

## Demo

Build and run the `RSKImageCropperExample` project in Xcode to see `RSKImageCropper` in action.
Have fun. Fork and send pull requests. Figure out hooks for customization.

## Privacy

`RSKImageCropper` doesn't require a privacy manifest. According to [information received from Apple](https://developer.apple.com/forums/thread/746481?answerId=782256022#782256022), we should avoid adding an empty privacy manifest to our frameworks.

## Contact

Ruslan Skorb

- http://github.com/ruslanskorb
- http://twitter.com/ruslanskorb
- [email protected]

## License

This project is available under the MIT license. See the LICENSE file for more info. Attribution by linking to the [project page](https://github.com/ruslanskorb/RSKImageCropper) is appreciated.