123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520 |
- //
- // UIImage+Extension.m
- // MIT_Endorsement
- //
- // Created by 翟玉磊 on 2017/12/15.
- // Copyright © 2017年 翟玉磊. All rights reserved.
- //
- #import "UIImage+Extension.h"
- #import <AVFoundation/AVFoundation.h>
- #import <AssetsLibrary/AssetsLibrary.h>
- #import <Accelerate/Accelerate.h>
- static NSTimeInterval const ThumbnailImageTime = 10.0f;
- @implementation UIImage (Extension)
- /**
- * 根据图片名返回一张能够自由拉伸的图片 (从中间拉伸)
- */
- + (UIImage *)resizableImage:(NSString *)imgName
- {
- return [self resizableImage:imgName xPos:0.5 yPos:0.5];;
- }
- /**
- * 根据图片名返回一张能够自由拉伸的图片
- */
- + (UIImage *)resizableImage:(NSString *)imgName xPos:(CGFloat)xPos yPos:(CGFloat)yPos
- {
- UIImage *image = [UIImage imageNamed:imgName];
-
- return [image stretchableImageWithLeftCapWidth:image.size.width * xPos topCapHeight:image.size.height * yPos];
- }
- /**
- * 获取视频第一帧图片
- */
- + (UIImage *)getVideoFirstThumbnailImageWithVideoUrl:(NSURL *)videoUrl
- {
- AVURLAsset*asset = [[AVURLAsset alloc] initWithURL:videoUrl options:nil];
-
- NSParameterAssert(asset);
-
- AVAssetImageGenerator *assetImageGenerator =[[AVAssetImageGenerator alloc] initWithAsset:asset];
-
- assetImageGenerator.appliesPreferredTrackTransform = YES;
-
- assetImageGenerator.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;
-
- CGImageRef thumbnailImageRef = nil;
- CFTimeInterval thumbnailImageTime = ThumbnailImageTime;
- NSError *thumbnailImageGenerationError = nil;
-
- thumbnailImageRef = [assetImageGenerator copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 1.0f) actualTime:nil error:&thumbnailImageGenerationError];
-
- if(!thumbnailImageRef)
- {
- NSLog(@"======thumbnailImageGenerationError======= %@",thumbnailImageGenerationError);
- }
-
- return thumbnailImageRef ? [[UIImage alloc] initWithCGImage:thumbnailImageRef] : nil;
- }
- /// 根据url获取第一帧图片,获取任一帧图片
- - (UIImage *)thumbnailImageForVideo:(NSURL *)videoURL atTime:(NSTimeInterval)time {
-
- AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
- NSParameterAssert(asset);
- AVAssetImageGenerator *assetImageGenerator =[[AVAssetImageGenerator alloc] initWithAsset:asset];
- assetImageGenerator.appliesPreferredTrackTransform = YES;
- assetImageGenerator.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;
-
- CGImageRef thumbnailImageRef = NULL;
- CFTimeInterval thumbnailImageTime = time;
- NSError *thumbnailImageGenerationError = nil;
- thumbnailImageRef = [assetImageGenerator copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60)actualTime:NULL error:&thumbnailImageGenerationError];
-
- if(!thumbnailImageRef)
- NSLog(@"thumbnailImageGenerationError %@",thumbnailImageGenerationError);
-
- UIImage*thumbnailImage = thumbnailImageRef ? [[UIImage alloc]initWithCGImage: thumbnailImageRef] : nil;
-
- return thumbnailImage;
- }
- /**
- * 图片不被渲染
- *
- */
- + (UIImage *)imageAlwaysShowOriginalImageWithImageName:(NSString *)imageName
- {
- UIImage *image = [UIImage imageNamed:imageName];
- if ([image respondsToSelector:@selector(imageWithRenderingMode:)])
- { //iOS 7.0+
- return [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
- }else{
- return image;
- }
- }
- /**
- * 根据图片和颜色返回一张加深颜色以后的图片
- * 图片着色
- */
- + (UIImage *)colorizeImageWithSourceImage:(UIImage *)sourceImage color:(UIColor *)color
- {
- UIGraphicsBeginImageContext(CGSizeMake(sourceImage.size.width*2, sourceImage.size.height*2));
-
- CGContextRef ctx = UIGraphicsGetCurrentContext();
- CGRect area = CGRectMake(0, 0, sourceImage.size.width * 2, sourceImage.size.height * 2);
-
- CGContextScaleCTM(ctx, 1, -1);
- CGContextTranslateCTM(ctx, 0, -area.size.height);
-
- CGContextSaveGState(ctx);
- CGContextClipToMask(ctx, area, sourceImage.CGImage);
-
- [color set];
-
- CGContextFillRect(ctx, area);
-
- CGContextRestoreGState(ctx);
-
- CGContextSetBlendMode(ctx, kCGBlendModeMultiply);
-
- CGContextDrawImage(ctx, area, sourceImage.CGImage);
-
- UIImage *destImage = UIGraphicsGetImageFromCurrentImageContext();
-
- UIGraphicsEndImageContext();
-
- return destImage;
-
- }
- /**
- * 根据指定的图片颜色和图片大小获取指定的Image
- *
- * @param color 颜色
- * @param size 大小
- *
- */
- + (UIImage *)getImageWithColor:(UIColor *)color size:(CGSize)size
- {
- UIGraphicsBeginImageContextWithOptions(size, 0, [UIScreen mainScreen].scale);
- [color set];
- UIRectFill(CGRectMake(0, 0, size.width, size.height));
- UIImage *destImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- return destImage;
- }
- /**
- * 通过传入一个图片对象获取一张缩略图
- */
- + (UIImage *)getThumbnailImageWithImageObj:(id)imageObj
- {
- __block UIImage *image = nil;
- if ([imageObj isKindOfClass:[UIImage class]]) {
- return imageObj;
- }else if ([imageObj isKindOfClass:[ALAsset class]]){
- @autoreleasepool {
- ALAsset *asset = (ALAsset *)imageObj;
- return [UIImage imageWithCGImage:[asset aspectRatioThumbnail]];
- }
- }
- return image;
- }
- /**
- * 通过传入一个图片对象获取一张原始图
- */
- + (UIImage *)getOriginalImageWithImageObj:(id)imageObj
- {
- __block UIImage *image = nil;
- if ([imageObj isKindOfClass:[UIImage class]]) {
- return imageObj;
- }else if ([imageObj isKindOfClass:[ALAsset class]]){
- @autoreleasepool {
- ALAsset *asset = (ALAsset *)imageObj;
- return [UIImage imageWithCGImage:asset.defaultRepresentation.fullScreenImage];
- }
- }
- return image;
- }
- + (UIImage *)gradientColorImageFromColors:(NSArray*)colors gradientType:(GradientType)gradientType imgSize:(CGSize)imgSize {
- NSMutableArray *ar = [NSMutableArray array];
- for(UIColor *c in colors) {
- [ar addObject:(id)c.CGColor];
- }
- UIGraphicsBeginImageContextWithOptions(imgSize, YES, 1);
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGContextSaveGState(context);
- CGColorSpaceRef colorSpace = CGColorGetColorSpace([[colors lastObject] CGColor]);
- CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)ar, NULL);
- CGPoint start;
- CGPoint end;
- switch (gradientType) {
- case GradientTypeTopToBottom:
- start = CGPointMake(0.0, 0.0);
- end = CGPointMake(0.0, imgSize.height);
- break;
- case GradientTypeLeftToRight:
- start = CGPointMake(0.0, 0.0);
- end = CGPointMake(imgSize.width, 0.0);
- break;
- case GradientTypeUpleftToLowright:
- start = CGPointMake(0.0, 0.0);
- end = CGPointMake(imgSize.width, imgSize.height);
- break;
- case GradientTypeUprightToLowleft:
- start = CGPointMake(imgSize.width, 0.0);
- end = CGPointMake(0.0, imgSize.height);
- break;
- default:
- break;
- }
- CGContextDrawLinearGradient(context, gradient, start, end,kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
- UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
- CGGradientRelease(gradient);
- CGContextRestoreGState(context);
- CGColorSpaceRelease(colorSpace);
- UIGraphicsEndImageContext();
- return image;
- }
- /// 常用蓝色渐变图片
- + (UIImage *)commonRedGradientColorImageWithImgSize:(CGSize)imgSize {
- UIImage *image = [UIImage gradientColorImageFromColors:@[ColorFromHexString(@"#5D26FF"), ColorFromHexString(@"#9059FF")] gradientType:GradientTypeLeftToRight imgSize:imgSize];
- return image;
- }
- /// 获取模糊效果的图片
- /// @param image 要模糊的图片
- /// @param blur 要模糊的程度
- + (UIImage *)boxblurImage:(UIImage *)image withBlurNumber:(CGFloat)blur {
- if (blur < 0.f || blur > 1.f) {
- blur = 0.5f;
- }
-
- int boxSize = (int)(blur * 40);
- boxSize = boxSize - (boxSize % 2) + 1;
- CGImageRef img = image.CGImage;
- vImage_Buffer inBuffer, outBuffer;
- vImage_Error error;
- void *pixelBuffer;
-
- //从CGImage中获取数据
- CGDataProviderRef inProvider = CGImageGetDataProvider(img);
- CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
-
- //设置从CGImage获取对象的属性
- inBuffer.width = CGImageGetWidth(img);
- inBuffer.height = CGImageGetHeight(img);
- inBuffer.rowBytes = CGImageGetBytesPerRow(img);
- inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);
- 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);
- error = 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, kCGImageAlphaNoneSkipLast);
- CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
- UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
-
- //clean up CGContextRelease(ctx)
- CGColorSpaceRelease(colorSpace);
- free(pixelBuffer);
- CFRelease(inBitmapData);
- CGColorSpaceRelease(colorSpace);
- CGImageRelease(imageRef);
- return returnImage;
- }
-
- /// GPUImage的开源库实现毛玻璃效果(比较吃内存,相对Core Image好一点)
- /// blurRadius一般10~30之间就可以满足需求
- + (UIImage *)GPUImageStyleWithImage:(UIImage *)image withBlurRadius:(CGFloat)blurRadius {
-
- GPUImageGaussianBlurFilter *filter = [[GPUImageGaussianBlurFilter alloc] init];
- filter.blurRadiusInPixels = blurRadius;//值越大,模糊度越大
- UIImage *blurImage = [filter imageByFilteringImage:image];
- return blurImage;
-
- }
- /// 修改图片颜色
- /// @param color 要修改的颜色
- - (UIImage*)imageChangeColor:(UIColor*)color {
- //获取画布
- UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
- //画笔沾取颜色
- [color setFill];
-
- CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
- UIRectFill(bounds);
- //绘制一次
- [self drawInRect:bounds blendMode:kCGBlendModeOverlay alpha:1.0f];
- //再绘制一次
- [self drawInRect:bounds blendMode:kCGBlendModeDestinationIn alpha:1.0f];
- //获取图片
- UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- return img;
- }
- // 以图片中心为中心,以最小边为边长,裁剪正方形图片
- +(UIImage *)cropSquareImage:(UIImage *)image{
-
- CGImageRef sourceImageRef = [image CGImage];//将UIImage转换成CGImageRef
-
- CGFloat _imageWidth = image.size.width * image.scale;
- CGFloat _imageHeight = image.size.height * image.scale;
- CGFloat _width = _imageWidth > _imageHeight ? _imageHeight : _imageWidth;
- CGFloat _offsetX = (_imageWidth - _width) / 2;
- CGFloat _offsetY = (_imageHeight - _width) / 2;
-
- CGRect rect = CGRectMake(_offsetX, _offsetY, _width, _width);
- CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect);//按照给定的矩形区域进行剪裁
- UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
-
- return newImage;
- }
- // 以图片中心为中心,以最小边为边长,裁剪圆形图片
- + (UIImage *)imageWithClipImage:(UIImage *)image {
- //1.开启跟原始图片一样大小的上下文
- UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
- //2.设置一个圆形裁剪区域
- //2.1绘制一个圆形
- UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
- //2.2.把圆形的路径设置成裁剪区域
- [path addClip];//超过裁剪区域以外的内容都给裁剪掉
- //3.把图片绘制到上下文当中(超过裁剪区域以外的内容都给裁剪掉)
- [image drawAtPoint:CGPointZero];
- //4.从上下文当中取出图片
- UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
- //5.关闭上下文
- UIGraphicsEndImageContext();
- return newImage;
- }
- // 获取gif图
- + (UIImage *)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 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)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 <rdar://problem/7689300> and <http://webkit.org/b/36082>
- // for more information.
-
- if (frameDuration < 0.011f) {
- frameDuration = 0.100f;
- }
-
- CFRelease(cfFrameProperties);
- return frameDuration;
- }
- + (UIImage *)animatedGIFNamed:(NSString *)name {
- if (![name hasSuffix:@".gif"]) {
- return [UIImage imageNamed:name];
- }
-
- CGFloat scale = [UIScreen mainScreen].scale;
-
- if (scale > 1.0f) {
- NSString *retinaPath = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:@"@2x"] ofType:nil];
-
- NSData *data = [NSData dataWithContentsOfFile:retinaPath];
-
- if (data) {
- return [UIImage animatedGIFWithData:data];
- }
-
- NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:nil];
-
- data = [NSData dataWithContentsOfFile:path];
-
- if (data) {
- return [UIImage animatedGIFWithData:data];
- }
-
- return [UIImage imageNamed:name];
- }
- else {
- NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:nil];
-
- NSData *data = [NSData dataWithContentsOfFile:path];
-
- if (data) {
- return [UIImage animatedGIFWithData:data];
- }
-
- return [UIImage imageNamed:name];
- }
- }
- /// 回去变灰图片
- + (UIImage*)getGrayImage:(UIImage*)oldImage {
- int bitmapInfo = kCGImageAlphaPremultipliedLast;
- int width = oldImage.size.width*[UIScreen mainScreen].scale;
- int height = oldImage.size.height*[UIScreen mainScreen].scale;
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
- CGContextRef context = CGBitmapContextCreate (nil, width, height, 8, 0, colorSpace, bitmapInfo);
- CGColorSpaceRelease(colorSpace);
- if (context == NULL) {return nil;}
- CGContextDrawImage(context, CGRectMake(0, 0, width, height), oldImage.CGImage);
- UIImage *grayImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];
- CGContextRelease(context);
- return grayImage;
-
- // CGImageRef inflatedImageRef = CGBitmapContextCreateImage(context);
- // UIImage *grayImage = [UIImage imageWithCGImage:inflatedImageRef];
- // CGImageRelease(inflatedImageRef);
-
- // int width = image.size.width;
- // int height = image.size.height;
- //
- // //第一步:开辟颜色空间
- // CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceGray();
- //
- // //第二步:创建颜色空间的上下文
- // CGContextRef contextRef = CGBitmapContextCreate(nil, width, height, 8, 0,colorSpaceRef, kCGImageAlphaNone);
- //
- // if (contextRef == nil)
- // {
- // return nil;
- // }
- // //第三步:渲染图片
- // CGContextDrawImage(contextRef, CGRectMake(0, 0, width, height), image.CGImage);
- //
- // //第四步:创建图片 将绘制的颜色空间转成CGImage
- // CGImageRef grayImageRef = CGBitmapContextCreateImage(contextRef);
- //
- // //第五步:将C/C++图片转成UIImage
- //
- // UIImage * newImage = [UIImage imageWithCGImage:grayImageRef];
- //
- // //释放内存
- // CGColorSpaceRelease(colorSpaceRef);
- // CGContextRelease(contextRef);
- // CGImageRelease(grayImageRef);
- //
- // return newImage;
- }
- @end
|