// // TZImageCropManager.m // TZImagePickerController // // Created by 谭真 on 2016/12/5. // Copyright © 2016年 谭真. All rights reserved. // #import "TZImageCropManager.h" #import "UIView+Layout.h" #import #import "TZImageManager.h" @implementation TZImageCropManager /// 裁剪框背景的处理 + (void)overlayClippingWithView:(UIView *)view cropRect:(CGRect)cropRect containerView:(UIView *)containerView needCircleCrop:(BOOL)needCircleCrop { UIBezierPath *path= [UIBezierPath bezierPathWithRect:[UIScreen mainScreen].bounds]; CAShapeLayer *layer = [CAShapeLayer layer]; if (needCircleCrop) { // 圆形裁剪框 [path appendPath:[UIBezierPath bezierPathWithArcCenter:containerView.center radius:cropRect.size.width / 2 startAngle:0 endAngle: 2 * M_PI clockwise:NO]]; } else { // 矩形裁剪框 [path appendPath:[UIBezierPath bezierPathWithRect:cropRect]]; } layer.path = path.CGPath; layer.fillRule = kCAFillRuleEvenOdd; layer.fillColor = [[UIColor blackColor] CGColor]; layer.opacity = 0.5; [view.layer addSublayer:layer]; } /// 获得裁剪后的图片 + (UIImage *)cropImageView:(UIImageView *)imageView toRect:(CGRect)rect zoomScale:(double)zoomScale containerView:(UIView *)containerView { CGAffineTransform transform = CGAffineTransformIdentity; // 平移的处理 CGRect imageViewRect = [imageView convertRect:imageView.bounds toView:containerView]; CGPoint point = CGPointMake(imageViewRect.origin.x + imageViewRect.size.width / 2, imageViewRect.origin.y + imageViewRect.size.height / 2); CGFloat xMargin = containerView.tz_width - CGRectGetMaxX(rect) - rect.origin.x; CGPoint zeroPoint = CGPointMake((CGRectGetWidth(containerView.frame) - xMargin) / 2, containerView.center.y); CGPoint translation = CGPointMake(point.x - zeroPoint.x, point.y - zeroPoint.y); transform = CGAffineTransformTranslate(transform, translation.x, translation.y); // 缩放的处理 transform = CGAffineTransformScale(transform, zoomScale, zoomScale); CGImageRef imageRef = [self newTransformedImage:transform sourceImage:imageView.image.CGImage sourceSize:imageView.image.size outputWidth:rect.size.width * [UIScreen mainScreen].scale cropSize:rect.size imageViewSize:imageView.frame.size]; UIImage *cropedImage = [UIImage imageWithCGImage:imageRef]; cropedImage = [[TZImageManager manager] fixOrientation:cropedImage]; CGImageRelease(imageRef); return cropedImage; } + (CGImageRef)newTransformedImage:(CGAffineTransform)transform sourceImage:(CGImageRef)sourceImage sourceSize:(CGSize)sourceSize outputWidth:(CGFloat)outputWidth cropSize:(CGSize)cropSize imageViewSize:(CGSize)imageViewSize { CGImageRef source = [self newScaledImage:sourceImage toSize:sourceSize]; CGFloat aspect = cropSize.height/cropSize.width; CGSize outputSize = CGSizeMake(outputWidth, outputWidth*aspect); CGContextRef context = CGBitmapContextCreate(NULL, outputSize.width, outputSize.height, CGImageGetBitsPerComponent(source), 0, CGImageGetColorSpace(source), CGImageGetBitmapInfo(source)); CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]); CGContextFillRect(context, CGRectMake(0, 0, outputSize.width, outputSize.height)); CGAffineTransform uiCoords = CGAffineTransformMakeScale(outputSize.width / cropSize.width, outputSize.height / cropSize.height); uiCoords = CGAffineTransformTranslate(uiCoords, cropSize.width/2.0, cropSize.height / 2.0); uiCoords = CGAffineTransformScale(uiCoords, 1.0, -1.0); CGContextConcatCTM(context, uiCoords); CGContextConcatCTM(context, transform); CGContextScaleCTM(context, 1.0, -1.0); CGContextDrawImage(context, CGRectMake(-imageViewSize.width/2, -imageViewSize.height/2.0, imageViewSize.width, imageViewSize.height), source); CGImageRef resultRef = CGBitmapContextCreateImage(context); CGContextRelease(context); CGImageRelease(source); return resultRef; } + (CGImageRef)newScaledImage:(CGImageRef)source toSize:(CGSize)size { CGSize srcSize = size; CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, 0, rgbColorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); CGColorSpaceRelease(rgbColorSpace); CGContextSetInterpolationQuality(context, kCGInterpolationNone); CGContextTranslateCTM(context, size.width/2, size.height/2); CGContextDrawImage(context, CGRectMake(-srcSize.width/2, -srcSize.height/2, srcSize.width, srcSize.height), source); CGImageRef resultRef = CGBitmapContextCreateImage(context); CGContextRelease(context); return resultRef; } /// 获取圆形图片 + (UIImage *)circularClipImage:(UIImage *)image { UIGraphicsBeginImageContextWithOptions(image.size, NO, [UIScreen mainScreen].scale); CGContextRef ctx = UIGraphicsGetCurrentContext(); CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height); CGContextAddEllipseInRect(ctx, rect); CGContextClip(ctx); [image drawInRect:rect]; UIImage *circleImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return circleImage; } @end @implementation UIImage (TZGif) + (UIImage *)sd_tz_animatedGIFWithData:(NSData *)data { if (!data) { return nil; } CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); size_t count = CGImageSourceGetCount(source); UIImage *animatedImage; if (count <= 1) { animatedImage = [[UIImage alloc] initWithData:data]; } else { NSMutableArray *images = [NSMutableArray array]; NSTimeInterval duration = 0.0f; for (size_t i = 0; i < count; i++) { CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL); if (!image) { continue; } duration += [self sd_frameDurationAtIndex:i source:source]; [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]]; CGImageRelease(image); } if (!duration) { duration = (1.0f / 10.0f) * count; } animatedImage = [UIImage animatedImageWithImages:images duration:duration]; } CFRelease(source); return animatedImage; } + (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source { float frameDuration = 0.1f; CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil); NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties; NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary]; NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime]; if (delayTimeUnclampedProp) { frameDuration = [delayTimeUnclampedProp floatValue]; } else { NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime]; if (delayTimeProp) { frameDuration = [delayTimeProp floatValue]; } } // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify // a duration of <= 10 ms. See and // for more information. if (frameDuration < 0.011f) { frameDuration = 0.100f; } CFRelease(cfFrameProperties); return frameDuration; } @end