|
@@ -0,0 +1,642 @@
|
|
|
+//
|
|
|
+// UIImage+UIImage_NXCategory.m
|
|
|
+// AKImovie
|
|
|
+//
|
|
|
+// Created by AK on 16/2/21.
|
|
|
+// Copyright © 2016年 ak. All rights reserved.
|
|
|
+//
|
|
|
+
|
|
|
+#import "UIImage+NXCategory.h"
|
|
|
+#import <Accelerate/Accelerate.h>
|
|
|
+
|
|
|
+@implementation UIImage (NXCategory)
|
|
|
+
|
|
|
+#pragma mark - blur 效果
|
|
|
++ (UIImage *)nx_blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur
|
|
|
+{
|
|
|
+ CIImage *inputImage = [CIImage imageWithCGImage:image.CGImage];
|
|
|
+ CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"
|
|
|
+ keysAndValues:kCIInputImageKey, inputImage, @"inputRadius", @(blur), nil];
|
|
|
+
|
|
|
+ CIImage *outputImage = filter.outputImage;
|
|
|
+ CIContext *context = [CIContext contextWithOptions:nil];
|
|
|
+ CGImageRef outImage = [context createCGImage:outputImage fromRect:[outputImage extent]];
|
|
|
+ return [UIImage imageWithCGImage:outImage];
|
|
|
+}
|
|
|
+
|
|
|
++ (UIImage *)nx_boxblurImage:(UIImage *)toBlurImage
|
|
|
+{
|
|
|
+ UIImage *newImage =
|
|
|
+
|
|
|
+ [toBlurImage nx_scaleToSize:CGSizeMake(toBlurImage.size.width / 2., toBlurImage.size.height / 2.)];
|
|
|
+
|
|
|
+ NSData *jpgData = UIImageJPEGRepresentation(newImage, 0.01);
|
|
|
+
|
|
|
+ UIImage *image = [UIImage imageWithData:jpgData];
|
|
|
+ CGFloat blur = 0.3f;
|
|
|
+
|
|
|
+ int boxSize = (int)(blur * 40);
|
|
|
+ boxSize = boxSize - (boxSize % 2) + 1;
|
|
|
+
|
|
|
+ CGImageRef img = image.CGImage;
|
|
|
+ vImage_Buffer inBuffer, outBuffer;
|
|
|
+ vImage_Error error;
|
|
|
+ void *pixelBuffer;
|
|
|
+
|
|
|
+ // create vImage_Buffer with data from CGImageRef
|
|
|
+ CGDataProviderRef inProvider = CGImageGetDataProvider(img);
|
|
|
+ CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
|
|
|
+
|
|
|
+ inBuffer.width = CGImageGetWidth(img);
|
|
|
+ inBuffer.height = CGImageGetHeight(img);
|
|
|
+ inBuffer.rowBytes = CGImageGetBytesPerRow(img);
|
|
|
+
|
|
|
+ inBuffer.data = (void *)CFDataGetBytePtr(inBitmapData);
|
|
|
+
|
|
|
+ // create vImage_Buffer for output
|
|
|
+ pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
|
|
|
+
|
|
|
+ if (pixelBuffer == NULL) NSLog(@"No pixelbuffer");
|
|
|
+
|
|
|
+ outBuffer.data = pixelBuffer;
|
|
|
+ outBuffer.width = CGImageGetWidth(img);
|
|
|
+ outBuffer.height = CGImageGetHeight(img);
|
|
|
+ outBuffer.rowBytes = CGImageGetBytesPerRow(img);
|
|
|
+
|
|
|
+ // perform convolution
|
|
|
+ error =
|
|
|
+ vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend)
|
|
|
+ ?: vImageBoxConvolve_ARGB8888(&outBuffer, &inBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend)
|
|
|
+ ?: vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL,
|
|
|
+ kvImageEdgeExtend);
|
|
|
+
|
|
|
+ if (error)
|
|
|
+ {
|
|
|
+ NSLog(@"error from convolution %ld", error);
|
|
|
+ }
|
|
|
+
|
|
|
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
|
|
+ CGContextRef ctx = CGBitmapContextCreate(outBuffer.data, outBuffer.width, outBuffer.height, 8, outBuffer.rowBytes,
|
|
|
+ colorSpace, (CGBitmapInfo)kCGImageAlphaNoneSkipLast);
|
|
|
+ CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
|
|
|
+ UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
|
|
|
+
|
|
|
+ // clean up
|
|
|
+ CGContextRelease(ctx);
|
|
|
+ CGColorSpaceRelease(colorSpace);
|
|
|
+
|
|
|
+ free(pixelBuffer);
|
|
|
+ CFRelease(inBitmapData);
|
|
|
+ CGImageRelease(imageRef);
|
|
|
+
|
|
|
+ return returnImage;
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark - 旋转
|
|
|
++ (UIImage *)nx_fixOrientation:(UIImage *)aImage isFront:(BOOL)isFront;
|
|
|
+{
|
|
|
+ // No-op if the orientation is already correct
|
|
|
+ if (aImage.imageOrientation == UIImageOrientationUp) return aImage;
|
|
|
+
|
|
|
+ // We need to calculate the proper transformation to make the image upright.
|
|
|
+ // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
|
|
|
+ CGAffineTransform transform = CGAffineTransformIdentity;
|
|
|
+
|
|
|
+ if (isFront)
|
|
|
+ {
|
|
|
+ transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
|
|
|
+ transform = CGAffineTransformScale(transform, -1, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (aImage.imageOrientation)
|
|
|
+ {
|
|
|
+ case UIImageOrientationDown:
|
|
|
+ case UIImageOrientationDownMirrored:
|
|
|
+ transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
|
|
|
+ transform = CGAffineTransformRotate(transform, M_PI);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case UIImageOrientationLeft:
|
|
|
+ case UIImageOrientationLeftMirrored:
|
|
|
+ transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
|
|
|
+ transform = CGAffineTransformRotate(transform, M_PI_2);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case UIImageOrientationRight:
|
|
|
+ case UIImageOrientationRightMirrored:
|
|
|
+ transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
|
|
|
+ transform = CGAffineTransformRotate(transform, -M_PI_2);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (aImage.imageOrientation)
|
|
|
+ {
|
|
|
+ case UIImageOrientationUpMirrored:
|
|
|
+ case UIImageOrientationDownMirrored:
|
|
|
+ transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
|
|
|
+ transform = CGAffineTransformScale(transform, -1, 1);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case UIImageOrientationLeftMirrored:
|
|
|
+ case UIImageOrientationRightMirrored:
|
|
|
+ transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
|
|
|
+ transform = CGAffineTransformScale(transform, -1, 1);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Now we draw the underlying CGImage into a new context, applying the
|
|
|
+ // transform
|
|
|
+ // calculated above.
|
|
|
+ CGContextRef ctx =
|
|
|
+ CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height, CGImageGetBitsPerComponent(aImage.CGImage),
|
|
|
+ 0, CGImageGetColorSpace(aImage.CGImage), CGImageGetBitmapInfo(aImage.CGImage));
|
|
|
+ CGContextConcatCTM(ctx, transform);
|
|
|
+ switch (aImage.imageOrientation)
|
|
|
+ {
|
|
|
+ case UIImageOrientationLeft:
|
|
|
+ case UIImageOrientationLeftMirrored:
|
|
|
+ case UIImageOrientationRight:
|
|
|
+ case UIImageOrientationRightMirrored:
|
|
|
+ // Grr...
|
|
|
+ CGContextDrawImage(ctx, CGRectMake(0, 0, aImage.size.height, aImage.size.width), aImage.CGImage);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ CGContextDrawImage(ctx, CGRectMake(0, 0, aImage.size.width, aImage.size.height), aImage.CGImage);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // And now we just create a new UIImage from the drawing context
|
|
|
+ CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
|
|
|
+ UIImage *img = [UIImage imageWithCGImage:cgimg];
|
|
|
+ CGContextRelease(ctx);
|
|
|
+ CGImageRelease(cgimg);
|
|
|
+ return img;
|
|
|
+}
|
|
|
+
|
|
|
+// 旋转
|
|
|
++ (UIImage *)nx_rotationImage:(UIImage *)image orientation:(UIImageOrientation)orientation
|
|
|
+{
|
|
|
+ long double rotate = 0.0;
|
|
|
+ CGRect rect;
|
|
|
+ float translateX = 0;
|
|
|
+ float translateY = 0;
|
|
|
+ float scaleX = 1.0;
|
|
|
+ float scaleY = 1.0;
|
|
|
+
|
|
|
+ switch (orientation)
|
|
|
+ {
|
|
|
+ case UIImageOrientationLeft:
|
|
|
+ rotate = M_PI_2;
|
|
|
+ rect = CGRectMake(0, 0, image.size.height, image.size.width);
|
|
|
+ translateX = 0;
|
|
|
+ translateY = -rect.size.width;
|
|
|
+ scaleY = rect.size.width / rect.size.height;
|
|
|
+ scaleX = rect.size.height / rect.size.width;
|
|
|
+ break;
|
|
|
+ case UIImageOrientationRight:
|
|
|
+ rotate = 3 * M_PI_2;
|
|
|
+ rect = CGRectMake(0, 0, image.size.height, image.size.width);
|
|
|
+ translateX = -rect.size.height;
|
|
|
+ translateY = 0;
|
|
|
+ scaleY = rect.size.width / rect.size.height;
|
|
|
+ scaleX = rect.size.height / rect.size.width;
|
|
|
+ break;
|
|
|
+ case UIImageOrientationDown:
|
|
|
+ rotate = M_PI;
|
|
|
+ rect = CGRectMake(0, 0, image.size.width, image.size.height);
|
|
|
+ translateX = -rect.size.width;
|
|
|
+ translateY = -rect.size.height;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ rotate = 0.0;
|
|
|
+ rect = CGRectMake(0, 0, image.size.width, image.size.height);
|
|
|
+ translateX = 0;
|
|
|
+ translateY = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ UIGraphicsBeginImageContext(rect.size);
|
|
|
+ CGContextRef context = UIGraphicsGetCurrentContext();
|
|
|
+ //做CTM变换
|
|
|
+ CGContextTranslateCTM(context, 0.0, rect.size.height);
|
|
|
+ CGContextScaleCTM(context, 1.0, -1.0);
|
|
|
+ CGContextRotateCTM(context, rotate);
|
|
|
+ CGContextTranslateCTM(context, translateX, translateY);
|
|
|
+
|
|
|
+ CGContextScaleCTM(context, scaleX, scaleY);
|
|
|
+ //绘制图片
|
|
|
+ CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);
|
|
|
+
|
|
|
+ UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
|
|
|
+ NSLog(@"image size %f---%f", image.size.width, image.size.height);
|
|
|
+ UIGraphicsEndImageContext();
|
|
|
+ return newPic;
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark - 缩放
|
|
|
+- (UIImage *)nx_scaleToSize:(CGSize)size
|
|
|
+{
|
|
|
+ CGFloat width = CGImageGetWidth(self.CGImage);
|
|
|
+ CGFloat height = CGImageGetHeight(self.CGImage);
|
|
|
+
|
|
|
+ float verticalRadio = size.height * 1.0 / height;
|
|
|
+ float horizontalRadio = size.width * 1.0 / width;
|
|
|
+
|
|
|
+ float radio = 1;
|
|
|
+ if (verticalRadio > 1 && horizontalRadio > 1)
|
|
|
+ {
|
|
|
+ radio = verticalRadio > horizontalRadio ? horizontalRadio : verticalRadio;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ radio = verticalRadio < horizontalRadio ? verticalRadio : horizontalRadio;
|
|
|
+ }
|
|
|
+
|
|
|
+ width = width * radio;
|
|
|
+ height = height * radio;
|
|
|
+
|
|
|
+ int xPos = (size.width - width) / 2;
|
|
|
+ int yPos = (size.height - height) / 2;
|
|
|
+
|
|
|
+ // 创建一个bitmap的context
|
|
|
+ // 并把它设置成为当前正在使用的context
|
|
|
+ UIGraphicsBeginImageContext(size);
|
|
|
+
|
|
|
+ // 绘制改变大小的图片
|
|
|
+ [self drawInRect:CGRectMake(xPos, yPos, width, height)];
|
|
|
+
|
|
|
+ // 从当前context中创建一个改变大小后的图片
|
|
|
+ UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
|
+
|
|
|
+ // 使当前的context出堆栈
|
|
|
+ UIGraphicsEndImageContext();
|
|
|
+
|
|
|
+ // 返回新的改变大小后的图片
|
|
|
+ return scaledImage;
|
|
|
+}
|
|
|
+
|
|
|
+//按照最短边缩放 maxlength 边长最大值
|
|
|
+- (UIImage *)nx_scaleWithMaxLength:(float)maxLength
|
|
|
+{
|
|
|
+ if (self.size.width > maxLength || self.size.height > maxLength)
|
|
|
+ {
|
|
|
+ float maxWidth = maxLength;
|
|
|
+ float maxHeight = maxLength;
|
|
|
+
|
|
|
+ if (self.size.width != self.size.height)
|
|
|
+ {
|
|
|
+ if (self.size.width > self.size.height)
|
|
|
+ {
|
|
|
+ //按照宽 来缩放
|
|
|
+ float imageScale = maxLength / self.size.width;
|
|
|
+ maxHeight = self.size.height * imageScale;
|
|
|
+ }
|
|
|
+ else if (self.size.width < self.size.height)
|
|
|
+ {
|
|
|
+ float imageScale = maxLength / self.size.height;
|
|
|
+
|
|
|
+ maxWidth = self.size.width * imageScale;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 返回新的改变大小后的图片
|
|
|
+ return [self nx_scaleToSize:CGSizeMake(maxWidth, maxHeight)];
|
|
|
+ }
|
|
|
+
|
|
|
+ return self;
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark - 截取
|
|
|
+- (UIImage *)nx_imageByCroppingWithStyle:(NXCropImageStyle)style
|
|
|
+{
|
|
|
+ CGRect rect = CGRectZero;
|
|
|
+ switch (style)
|
|
|
+ {
|
|
|
+ case NXCropImageStyleLeft:
|
|
|
+ rect = CGRectMake(0, 0, self.size.width / 2, self.size.height);
|
|
|
+ break;
|
|
|
+ case NXCropImageStyleCenter:
|
|
|
+ rect = CGRectMake(self.size.width / 4, 0, self.size.width / 2, self.size.height);
|
|
|
+ break;
|
|
|
+ case NXCropImageStyleRight:
|
|
|
+ rect = CGRectMake(self.size.width / 2, 0, self.size.width / 2, self.size.height);
|
|
|
+ break;
|
|
|
+ case NXCropImageStyleLeftOneOfThird:
|
|
|
+ rect = CGRectMake(0, 0, self.size.width / 3, self.size.height);
|
|
|
+ break;
|
|
|
+ case NXCropImageStyleCenterOneOfThird:
|
|
|
+ rect = CGRectMake(self.size.width / 3, 0, self.size.width / 3, self.size.height);
|
|
|
+ break;
|
|
|
+ case NXCropImageStyleRightOneOfThird:
|
|
|
+ rect = CGRectMake(self.size.width / 3 * 2, 0, self.size.width / 3, self.size.height);
|
|
|
+ break;
|
|
|
+ case NXCropImageStyleLeftQuarter:
|
|
|
+ rect = CGRectMake(0, 0, self.size.width / 4, self.size.height);
|
|
|
+ break;
|
|
|
+ case NXCropImageStyleCenterLeftQuarter:
|
|
|
+ rect = CGRectMake(self.size.width / 4, 0, self.size.width / 4, self.size.height);
|
|
|
+ break;
|
|
|
+ case NXCropImageStyleCenterRightQuarter:
|
|
|
+ rect = CGRectMake(self.size.width / 4 * 2, 0, self.size.width / 4, self.size.height);
|
|
|
+ break;
|
|
|
+ case NXCropImageStyleRightQuarter:
|
|
|
+ rect = CGRectMake(self.size.width / 4 * 3, 0, self.size.width / 4, self.size.height);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return [self imageByCroppingWithRect:rect];
|
|
|
+}
|
|
|
+
|
|
|
+- (UIImage *)imageByCroppingWithRect:(CGRect)rect
|
|
|
+{
|
|
|
+ CGImageRef imageRef = self.CGImage;
|
|
|
+ CGImageRef imagePartRef = CGImageCreateWithImageInRect(imageRef, rect);
|
|
|
+ UIImage *cropImage = [UIImage imageWithCGImage:imagePartRef];
|
|
|
+ CGImageRelease(imagePartRef);
|
|
|
+ return cropImage;
|
|
|
+}
|
|
|
+
|
|
|
+- (UIImage *)nx_cropImageToSquare{
|
|
|
+
|
|
|
+ if(self.size.width == self.size.height)
|
|
|
+ {
|
|
|
+ return self;
|
|
|
+ }
|
|
|
+ double w = self.size.width;
|
|
|
+ double h = self.size.height;
|
|
|
+ double m = MIN(w, h);
|
|
|
+ CGRect rect = CGRectMake((self.size.width - m)/2.0f , (self.size.height - m)/2.0f, m, m);
|
|
|
+ return [self imageByCroppingWithRect:rect];
|
|
|
+}
|
|
|
+
|
|
|
+- (UIImage *)nx_zoomWithSize:(CGSize)size{
|
|
|
+
|
|
|
+ if(self == nil)
|
|
|
+ {
|
|
|
+ return nil;
|
|
|
+ }
|
|
|
+
|
|
|
+ double w = self.size.width;
|
|
|
+ double h =self.size.height;
|
|
|
+ double vRatio = w / size.width;
|
|
|
+ double hRatio = h / size.height;
|
|
|
+ double ratio = MAX(vRatio, hRatio);
|
|
|
+ w /= ratio;
|
|
|
+ h /= ratio;
|
|
|
+ CGRect drawRect = CGRectMake((size.width - w)/2.0f , (size.height - h)/2.0f, w, h);
|
|
|
+ // 创建一个bitmap的context
|
|
|
+ // 并把它设置成为当前正在使用的context
|
|
|
+ UIGraphicsBeginImageContext(size);
|
|
|
+ // 绘制改变大小的图片
|
|
|
+ [self drawInRect:drawRect];
|
|
|
+ // 从当前context中创建一个改变大小后的图片
|
|
|
+ UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
|
+ // 使当前的context出堆栈
|
|
|
+ UIGraphicsEndImageContext();
|
|
|
+ return scaledImage;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+- (UIImage *)nx_zoomImageToSquare
|
|
|
+{
|
|
|
+ if (self == nil)
|
|
|
+ {
|
|
|
+ return nil;
|
|
|
+ }
|
|
|
+ double tw = MIN(self.size.width, self.size.height);
|
|
|
+
|
|
|
+ return [self nx_scaleToSize:CGSizeMake(tw, tw)];
|
|
|
+}
|
|
|
+
|
|
|
+//截屏 有透明的
|
|
|
++ (UIImage *)nx_screenHierarchyShots:(UIView *)view { return [UIImage nx_screenHierarchyShots:view isOpaque:NO]; }
|
|
|
+//高清截屏 opaque 是否有透明图层
|
|
|
++ (UIImage *)nx_screenHierarchyShots:(UIView *)view isOpaque:(BOOL)opaque
|
|
|
+{
|
|
|
+ // size——同UIGraphicsBeginImageContext
|
|
|
+ // opaque—透明开关,如果图形完全不用透明,设置为YES以优化位图的存储。
|
|
|
+ // scale—–缩放因子
|
|
|
+ UIGraphicsBeginImageContextWithOptions(view.bounds.size, opaque, 0);
|
|
|
+ [view.layer renderInContext:UIGraphicsGetCurrentContext()];
|
|
|
+ UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
|
|
+ UIGraphicsEndImageContext();
|
|
|
+ return image;
|
|
|
+}
|
|
|
+
|
|
|
+/// 获得裁剪后的图片
|
|
|
++ (UIImage *)nx_cropImageView:(UIImageView *)imageView
|
|
|
+ toRect:(CGRect)rect
|
|
|
+ zoomScale:(double)zoomScale
|
|
|
+ containerView:(UIView *)containerView
|
|
|
+ outputWith:(CGFloat)outputWith
|
|
|
+{
|
|
|
+ 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);
|
|
|
+
|
|
|
+ CGPoint zeroPoint =
|
|
|
+ CGPointMake(CGRectGetWidth(containerView.frame) / 2., CGRectGetHeight(containerView.frame) / 2.);
|
|
|
+
|
|
|
+ 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 nx_newTransformedImage:transform
|
|
|
+ sourceImage:imageView.image.CGImage
|
|
|
+ sourceSize:imageView.image.size
|
|
|
+ outputWidth:outputWith
|
|
|
+ cropSize:rect.size
|
|
|
+ imageViewSize:imageView.frame.size];
|
|
|
+ UIImage *cropedImage = [UIImage imageWithCGImage:imageRef];
|
|
|
+ CGImageRelease(imageRef);
|
|
|
+ return cropedImage;
|
|
|
+}
|
|
|
+
|
|
|
++ (CGImageRef)nx_newTransformedImage:(CGAffineTransform)transform
|
|
|
+ sourceImage:(CGImageRef)sourceImage
|
|
|
+ sourceSize:(CGSize)sourceSize
|
|
|
+ outputWidth:(CGFloat)outputWidth
|
|
|
+ cropSize:(CGSize)cropSize
|
|
|
+ imageViewSize:(CGSize)imageViewSize
|
|
|
+{
|
|
|
+ CGImageRef source = [self nx_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)nx_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;
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark - 圆角
|
|
|
++ (UIImage *)nx_circleImage:(UIImage *)img
|
|
|
+{
|
|
|
+ return [self nx_circleImage:img cuttingDirection:UIRectCornerAllCorners cornerRadii:img.size.height/2. borderWidth:0 borderColor: [UIColor clearColor] backgroundColor: [UIColor clearColor]];
|
|
|
+}
|
|
|
+
|
|
|
++ (UIImage *)nx_circleImage:(UIImage *)image cuttingDirection:(UIRectCorner)direction cornerRadii:(CGFloat)cornerRadii borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor backgroundColor:(UIColor *)backgroundColor
|
|
|
+{
|
|
|
+ //处理后的数据
|
|
|
+ UIImage * newImage = nil;
|
|
|
+ if (image.size.height != 0 && image.size.width != 0)
|
|
|
+ {
|
|
|
+ if (cornerRadii == 0)
|
|
|
+ {
|
|
|
+ cornerRadii = image.size.height / 2;
|
|
|
+ }
|
|
|
+ CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
|
|
|
+ UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);
|
|
|
+ CGContextRef currnetContext = UIGraphicsGetCurrentContext();
|
|
|
+ if (currnetContext) {
|
|
|
+
|
|
|
+ UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:direction cornerRadii:CGSizeMake(cornerRadii - borderWidth, cornerRadii - borderWidth)];
|
|
|
+ CGContextAddPath(currnetContext,path.CGPath);
|
|
|
+ CGContextClip(currnetContext);
|
|
|
+
|
|
|
+ [image drawInRect:rect];
|
|
|
+ [borderColor setStroke];// 画笔颜色
|
|
|
+ [backgroundColor setFill];// 填充颜色
|
|
|
+ [path stroke];
|
|
|
+ [path fill];
|
|
|
+ newImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
|
+ UIGraphicsEndImageContext();
|
|
|
+ }
|
|
|
+
|
|
|
+ return newImage;
|
|
|
+ }
|
|
|
+
|
|
|
+ return newImage;
|
|
|
+}
|
|
|
+
|
|
|
++ (UIImage *)nx_launchImage
|
|
|
+{
|
|
|
+ CGSize viewSize = [UIScreen mainScreen].bounds.size;
|
|
|
+
|
|
|
+ NSString * viewOrientation = @"Portrait";
|
|
|
+ NSString * launchImageName = nil;
|
|
|
+ NSArray * imageDict = [[[NSBundle mainBundle] infoDictionary]valueForKey:@"UILaunchImages"];
|
|
|
+ for (NSDictionary * dict in imageDict)
|
|
|
+ {
|
|
|
+ CGSize imageSize = CGSizeFromString(dict[@"UILaunchImageSize"]);
|
|
|
+ if (CGSizeEqualToSize(imageSize, viewSize) && [viewOrientation isEqualToString:dict[@"UILaunchImageOrientation"]])
|
|
|
+ {
|
|
|
+ launchImageName = dict[@"UILaunchImageName"];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ UIImage * launchImage = [UIImage imageNamed:launchImageName];
|
|
|
+
|
|
|
+ return launchImage;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
++ (UIImage*)transparentBackClear:(UIImage*)image color:(UIColor*)color
|
|
|
+{
|
|
|
+ // 分配内存
|
|
|
+ const int imageWidth = image.size.width;
|
|
|
+ const int imageHeight = image.size.height;
|
|
|
+ size_t bytesPerRow = imageWidth * 4;
|
|
|
+ uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight);
|
|
|
+
|
|
|
+ // 创建context
|
|
|
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
|
|
+ CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace,
|
|
|
+ kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
|
|
|
+ CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);
|
|
|
+
|
|
|
+ // 遍历像素
|
|
|
+ int pixelNum = imageWidth * imageHeight;
|
|
|
+ uint32_t* pCurPtr = rgbImageBuf;
|
|
|
+ for (int i = 0; i < pixelNum; i++, pCurPtr++)
|
|
|
+ {
|
|
|
+ if ((*pCurPtr & 0xFFFFFF00) == 0xffffff00) {
|
|
|
+
|
|
|
+ // 此处把白色背景颜色给变为透明
|
|
|
+ uint8_t* ptr = (uint8_t*)pCurPtr;
|
|
|
+ ptr[0] = 0;
|
|
|
+
|
|
|
+ }else{
|
|
|
+
|
|
|
+ // 改成下面的代码,会将图片转成想要的
|
|
|
+ // uint8_t* ptr = (uint8_t*)pCurPtr;
|
|
|
+ //
|
|
|
+ // ptr[3] = 0; //0~255
|
|
|
+ //
|
|
|
+ // ptr[2] = 0;
|
|
|
+ //
|
|
|
+ // ptr[1] = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将内存转成image
|
|
|
+ CGDataProviderRef dataProvider =CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData);
|
|
|
+
|
|
|
+ CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight,8, 32, bytesPerRow, colorSpace,
|
|
|
+ kCGImageAlphaLast |kCGBitmapByteOrder32Little, dataProvider,
|
|
|
+ NULL, true,kCGRenderingIntentDefault);
|
|
|
+ CGDataProviderRelease(dataProvider);
|
|
|
+
|
|
|
+ UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];
|
|
|
+
|
|
|
+ // 释放
|
|
|
+ CGImageRelease(imageRef);
|
|
|
+ CGContextRelease(context);
|
|
|
+ CGColorSpaceRelease(colorSpace);
|
|
|
+
|
|
|
+ return resultUIImage;
|
|
|
+}
|
|
|
+
|
|
|
+void ProviderReleaseData (void *info, const void *data, size_t size)
|
|
|
+{
|
|
|
+ free((void*)data);
|
|
|
+}
|
|
|
+
|
|
|
+@end
|