这里是本人项目的里用的全部代码,可以直接拷贝使用:
CameraCutView.h
```
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface CameraCutView : UIView
@property (nonatomic) UIImage * mTargetImage;
@property (nonatomic) UIImage * mResultImage;
@property (nonatomic, assign) CGSize originalImageViewSize;
- (void) showCoverViewWithTargetImg;
//frame 相对于当前屏幕坐标 当前屏幕当中的裁剪范围
-(UIImage *) cutImageWithSpecificRect:(CGRect)frame;
- (UIImage *)selectImage;
// 旋转
- (void)rotationImage:(CGFloat)rotation ;
// 缩放大小
- (void)setZoomWithValue:(CGFloat)zoom;
@end
NS_ASSUME_NONNULL_END
```
CameraCutView.m
NS_ASSUME_NONNULL_END
#import "CameraCutView.h"
#import "UIImage+Util.h"
@interface CameraCutView ()
@end
@implementation CameraCutView{
UIImageView *_mCameraBgView;
}
- (instancetype)init{
if (self = [super init]) {
[self initUI];
return self;
}
return nil;
}
- (void)initUI{
self.backgroundColor = [UIColor clearColor];
}
- (void)showCoverViewWithTargetImg {
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
_mCameraBgView.backgroundColor = kColorHex(kColorWhite);
float scaleValue = [self getScaleNum:_mTargetImage];
_mTargetImage = [self scaleImage:_mTargetImage toScale:scaleValue];
if (_mTargetImage != nil) {
_mCameraBgView = [[UIImageView alloc] init];
}
float _imageScale = self.frame.size.width / _mTargetImage.size.width;
_mCameraBgView.frame = CGRectMake(0, 0, _mTargetImage.size.width * _imageScale, _mTargetImage.size.height * _imageScale);
_originalImageViewSize = CGSizeMake(_mTargetImage.size.width * _imageScale, _mTargetImage.size.height * _imageScale);
_mCameraBgView.image = self.mTargetImage;
[self addSubview:_mCameraBgView];
[self setUserGesture];
}
- (void)setUserGesture {
[_mCameraBgView setUserInteractionEnabled:YES];
//添加移动手势
UIPanGestureRecognizer *moveGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(moveImage:)];
[moveGes setMinimumNumberOfTouches:1];
[moveGes setMaximumNumberOfTouches:1];
[_mCameraBgView addGestureRecognizer:moveGes];
//添加缩放手势
UIPinchGestureRecognizer *scaleGes = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scaleImage:)];
[_mCameraBgView addGestureRecognizer:scaleGes];
//添加旋转手势
UIRotationGestureRecognizer *rotateGes = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotateImage:)];
[_mCameraBgView addGestureRecognizer:rotateGes];
}
// 上下移动
float _lastTransX = 0.0, _lastTransY = 0.0;
- (void)moveImage:(UIPanGestureRecognizer *)sender {
CGPoint translatedPoint = [sender translationInView:self];
if([sender state] == UIGestureRecognizerStateBegan) {
_lastTransX = 0.0;
_lastTransY = 0.0;
}
CGAffineTransform trans = CGAffineTransformMakeTranslation(translatedPoint.x - _lastTransX, translatedPoint.y - _lastTransY);
CGAffineTransform newTransform = CGAffineTransformConcat(_mCameraBgView.transform, trans);
_lastTransX = translatedPoint.x;
_lastTransY = translatedPoint.y;
if ([self isCanMove:newTransform]) {
_mCameraBgView.transform = newTransform;
}
}
// 旋转按钮事件
- (void)rotationImage:(CGFloat)rotation {
CGFloat newRotation = rotation;
NSLog(@"newRotation == %f", newRotation);
CGAffineTransform currentTransform = _mCameraBgView.transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform, newRotation);
[_mCameraBgView setTransform:newTransform];
_lastRotation = rotation;
}
// 放大、缩小按钮
- (void)setZoomWithValue:(CGFloat)zoom {
[self zoomImageWithScale:zoom];
}
// 缩放手势
float _lastScale = 1.0;
- (void)scaleImage:(UIPinchGestureRecognizer *)sender {
if([sender state] == UIGestureRecognizerStateBegan) {
_lastScale = 1.0;
return;
}
CGFloat scale = [sender scale]/_lastScale;
[self zoomImageWithScale:scale];
_lastScale = [sender scale];
}
- (void)zoomImageWithScale:(CGFloat)scale {
// scale 小于1为缩小
if (scale < 1) {
if (_mCameraBgView.size.width < kScreenWidth) {
return;
}
}
// scale 大于1为放大
if (scale > 1) {
if (_mCameraBgView.size.width > kScreenWidth * 3.5) {
return;
}
}
CGAffineTransform currentTransform = _mCameraBgView.transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[_mCameraBgView setTransform:newTransform];
}
// 旋转手势
float _lastRotation = 0.0;
- (void)rotateImage:(UIRotationGestureRecognizer *)sender {
if ([sender state] == UIGestureRecognizerStateEnded) {
_lastRotation = 0.0;
return;
}
CGFloat rotation = -_lastRotation + [sender rotation];
CGAffineTransform currentTransform = _mCameraBgView.transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform, rotation);
[_mCameraBgView setTransform:newTransform];
_lastRotation = [sender rotation];
}
/***
方法名称:cutImageWithSpecificRect
方法用途:根据特定的区域对图片进行裁剪
方法说明:核心裁剪方法CGImageCreateWithImageInRect(CGImageRef image,CGRect rect)
***/
- (UIImage *)cutImageWithSpecificRect:(CGRect)frame {
float zoomScale = [[_mCameraBgView.layer valueForKeyPath:@"transform.scale.x"] floatValue];
float rotate = [[_mCameraBgView.layer valueForKeyPath:@"transform.rotation.z"] floatValue];
float _imageScale = _mTargetImage.size.width/_originalImageViewSize.width;
//裁剪区域的Size_originalImageViewSize CGSize (width = 0, height = 0)
CGSize cropSize = CGSizeMake(frame.size.width/zoomScale, frame.size.height/zoomScale);
//裁剪区域的Origin
CGPoint cropperViewOrigin = CGPointMake((0.0 - _mCameraBgView.frame.origin.x + frame.origin.x)/zoomScale,
(0.0 - _mCameraBgView.frame.origin.y + frame.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);
}
CGRect CropRectinImage = CGRectMake((NSInteger)(cropperViewOrigin.x*_imageScale) ,(NSInteger)( cropperViewOrigin.y*_imageScale), (NSInteger)(cropSize.width*_imageScale),(NSInteger)(cropSize.height*_imageScale));
UIImage *rotInputImage = [_mTargetImage imageRotatedByRadians:rotate];
CGImageRef tmp = CGImageCreateWithImageInRect([rotInputImage CGImage], CropRectinImage);
self.mResultImage = [UIImage imageWithCGImage:tmp scale:_mTargetImage.scale orientation:_mTargetImage.imageOrientation];
CGImageRelease(tmp);
return self.mResultImage;
}
- (UIImage *)selectImage {
//self.image是拍照所得的照片
UIImage *image1 = _mTargetImage;
CGImageRef cgRef = image1.CGImage;
//实际照片大小与屏幕大小之比
CGFloat widthScale = image1.size.width / kScreenWidth;
CGFloat heightScale = image1.size.height / kScreenHeight;
//我们所拍照片其实是横屏的
//多减掉50是因为最后的效果图片的高度有偏差,不知道原因
CGFloat orignWidth = 226-50;//226
CGFloat orginHeight = 360;//360
CGFloat x = (kScreenHeight - orginHeight) * 0.5 * heightScale;
CGFloat y = (kScreenWidth - orignWidth) * 0.5 * widthScale;
CGFloat width = orginHeight * heightScale;
CGFloat height = orignWidth * widthScale;
CGRect r = CGRectMake(x, y, width, height);
CGImageRef imageRef = CGImageCreateWithImageInRect(cgRef, r);
UIImage *thumbScale = [UIImage imageWithCGImage:imageRef];
//
image1 = thumbScale;
return image1;
}
- (BOOL)isCanMove:(CGAffineTransform )newTransform {
if (_mCameraBgView.frame.size.height/2 - fabs(newTransform.ty)<=0 ||
_mCameraBgView.frame.size.width/2 - fabs(newTransform.tx) <=0) {
return NO;
} else {
return YES;
}
}
/***
方法名称:scaleImage:toScale:
方法用途:图片的伸缩处理
方法说明:scaleSize:放大或缩小的倍数
***/
- (UIImage *)scaleImage:(UIImage *)image toScale:(float)scaleSize {
UIGraphicsBeginImageContext(CGSizeMake(image.size.width * scaleSize, image.size.height * scaleSize));
[image drawInRect:CGRectMake(0, 0, image.size.width * scaleSize, image.size.height * scaleSize)];
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}
/***
方法名称:getScaleNum:
方法用途:根据图片的宽度为基准,来获取图片伸缩放大的倍数
方法说明:
***/
- (float)getScaleNum:(UIImage *)targetImg {
CGRect r = [UIScreen mainScreen].bounds;
float preWidth = targetImg.size.width;
float scaleValue = 1;
// scaleValue = r.size.width/preWidth;
return scaleValue;
}
//图片复原
- (void)reset {
_mCameraBgView.transform = CGAffineTransformIdentity;
}
@end
UIImage+Util.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIImage (Util)
//设置的外围不变形内部平铺拉伸
- (UIImage*)resizeImageWithTop:(CGFloat)top andLeft:(CGFloat)left andBottom:(CGFloat)bottom andRight:(CGFloat)right;
- (UIImage *)imageRotatedByRadians:(CGFloat)radians;
- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees;
@end
NS_ASSUME_NONNULL_END
UIImage+Util.m
#import "UIImage+Util.h"
CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180/M_PI;};
@implementation UIImage (Util)
//设置的外围不变形内部平铺拉伸
- (UIImage*)resizeImageWithTop:(CGFloat)top andLeft:(CGFloat)left andBottom:(CGFloat)bottom andRight:(CGFloat)right{
UIImage *image = self;
// 设置端盖的值
CGFloat _top = image.size.height * top;
CGFloat _left = image.size.width * left;
CGFloat _bottom = image.size.height * bottom;
CGFloat _right = image.size.width * right;
// 设置端盖的值
UIEdgeInsets edgeInsets = UIEdgeInsetsMake(_top, _left, _bottom, _right);
// 设置拉伸的模式
UIImageResizingMode mode = UIImageResizingModeStretch;
// 拉伸图片
UIImage *newImage = [image resizableImageWithCapInsets:edgeInsets resizingMode:mode];
return newImage;
}
- (UIImage *)imageRotatedByRadians:(CGFloat)radians {
return [self imageRotatedByDegrees:RadiansToDegrees(radians)];
}
- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees {
// calculate the size of the rotated view's containing box for our drawing space
UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.size.width, self.size.height)];
CGAffineTransform t = CGAffineTransformMakeRotation(DegreesToRadians(degrees));
rotatedViewBox.transform = t;
CGSize rotatedSize = rotatedViewBox.frame.size;
// Create the bitmap context
UIGraphicsBeginImageContext(rotatedSize);
CGContextRef bitmap = UIGraphicsGetCurrentContext();
// Move the origin to the middle of the image so we will rotate and scale around the center.
CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);
// // Rotate the image context
CGContextRotateCTM(bitmap, DegreesToRadians(degrees));
// Now, draw the rotated/scaled image into the context
CGContextScaleCTM(bitmap, 1.0, -1.0);
CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), [self CGImage]);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
@end
下面是调用代码
@interface BitiPhotoVC ()
@property (nonatomic, strong) CameraCutView *cutView;
@end
// 图片展示
self.cutView.mTargetImage = [UIImage imageNamed:<#(nonnull NSString *)#>]
self.cutView.originalImageViewSize = CGSizeMake(width, height);
[self.cutView showCoverViewWithTargetImg];