123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- //
- // UIImage+HXExtension.m
- // HXPhotoPickerExample
- //
- // Created by Silence on 17/2/15.
- // Copyright © 2017年 Silence. All rights reserved.
- //
- #import "UIImage+HXExtension.h"
- #import "HXPhotoTools.h"
- #import <ImageIO/ImageIO.h>
- #import <Accelerate/Accelerate.h>
- @implementation UIImage (HXExtension)
- + (UIImage *)hx_imageNamed:(NSString *)imageName {
- if (!imageName) {
- return nil;
- }
- UIImage *image;
- NSBundle *bundle = [NSBundle hx_photoPickerBundle];
- if (bundle) {
- NSString *path = [bundle pathForResource:@"images" ofType:nil];
- path = [path stringByAppendingPathComponent:imageName];
- image = [UIImage imageNamed:path];
- }
- if (!image) {
- image = [self imageNamed:imageName];
- }
- return image;
- }
- + (UIImage *)hx_imageContentsOfFile:(NSString *)imageName {
- if (!imageName) {
- return nil;
- }
- UIImage *image;
- NSBundle *bundle = [NSBundle hx_photoPickerBundle];
- if (bundle) {
- NSString *path = [bundle pathForResource:@"images" ofType:nil];
- path = [path stringByAppendingPathComponent:imageName];
- image = [UIImage imageWithContentsOfFile:path];
- }
- if (!image) {
- image = [self imageNamed:imageName];
- }
- return image;
- }
- + (UIImage *)hx_thumbnailImageForVideo:(NSURL *)videoURL atTime:(NSTimeInterval)time {
- AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
- if (!asset) {
- return nil;
- }
- 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];
- UIImage*thumbnailImage = thumbnailImageRef ? [[UIImage alloc]initWithCGImage: thumbnailImageRef] : nil;
- CGImageRelease(thumbnailImageRef);
- return thumbnailImage;
- }
- + (UIImage *)hx_animatedGIFWithImageSourceRef:(CGImageSourceRef)source {
- //获取gif文件的帧数
- size_t count = CGImageSourceGetCount(source);
- UIImage *animatedImage;
- if (count > 1) { //大于一张图片时
- NSMutableArray *images = [NSMutableArray array];
- //设置gif播放的时间
- NSTimeInterval duration = 0.0f;
- for (size_t i = 0; i < count; i++) {
- //获取gif指定帧的像素位图
- 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];
- }
-
- return animatedImage;
- }
- + (UIImage *)hx_animatedGIFWithURL:(NSURL *)URL {
- if (!URL) {
- return nil;
- }
- CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)URL, NULL);
-
- UIImage *animatedImage = [self hx_animatedGIFWithImageSourceRef:source];
- if (!animatedImage) {
- animatedImage = [UIImage imageWithContentsOfFile:URL.relativePath];
- }
- CFRelease(source);
- return animatedImage;
- }
- + (UIImage *)hx_animatedGIFWithData:(NSData *)data {
- if (!data) {
- return nil;
- }
- //通过CFData读取gif文件的数据
- CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
-
- UIImage *animatedImage = [self hx_animatedGIFWithImageSourceRef:source];
- if (!animatedImage) {
- animatedImage = [UIImage imageWithData:data];
- }
-
- 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;
- //获取gif属性字典
- 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];
- }
- }
- //如果帧数小于0.1,则指定为0.1
- if (frameDuration < 0.011f) {
- frameDuration = 0.100f;
- }
- CFRelease(cfFrameProperties);
- return frameDuration;
- }
- - (UIImage *)hx_normalizedImage {
- if (self.imageOrientation == UIImageOrientationUp) return self;
-
- UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
- [self drawInRect:(CGRect){0, 0, self.size}];
- UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- return normalizedImage;
- }
- - (UIImage *)hx_scaleImagetoScale:(float)scaleSize {
-
- UIGraphicsBeginImageContext(CGSizeMake(self.size.width * scaleSize, self.size.height * scaleSize));
-
- [self drawInRect:CGRectMake(0, 0, self.size.width * scaleSize, self.size.height * scaleSize)];
- UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- return scaledImage;
- }
- - (UIImage *)hx_rotationImage:(UIImageOrientation)orient {
- CGRect bnds = CGRectZero;
- UIImage* copy = nil;
- CGContextRef ctxt = nil;
- CGImageRef imag = self.CGImage;
- CGRect rect = CGRectZero;
- CGAffineTransform tran = CGAffineTransformIdentity;
-
- rect.size.width = CGImageGetWidth(imag) * self.scale;
- rect.size.height = CGImageGetHeight(imag) * self.scale;
-
- while (rect.size.width * rect.size.height > 3 * 1000 * 1000) {
- rect.size.width /= 2;
- rect.size.height /= 2;
- }
-
- bnds = rect;
-
- switch (orient)
- {
- case UIImageOrientationUp:
- return self;
-
- case UIImageOrientationUpMirrored:
- tran = CGAffineTransformMakeTranslation(rect.size.width, 0.0);
- tran = CGAffineTransformScale(tran, -1.0, 1.0);
- break;
-
- case UIImageOrientationDown:
- tran = CGAffineTransformMakeTranslation(rect.size.width,
- rect.size.height);
- tran = CGAffineTransformRotate(tran, M_PI);
- break;
-
- case UIImageOrientationDownMirrored:
- tran = CGAffineTransformMakeTranslation(0.0, rect.size.height);
- tran = CGAffineTransformScale(tran, 1.0, -1.0);
- break;
-
- case UIImageOrientationLeft:
- bnds = swapWidthAndHeight(bnds);
- tran = CGAffineTransformMakeTranslation(0.0, rect.size.width);
- tran = CGAffineTransformRotate(tran, 3.0 * M_PI / 2.0);
- break;
-
- case UIImageOrientationLeftMirrored:
- bnds = swapWidthAndHeight(bnds);
- tran = CGAffineTransformMakeTranslation(rect.size.height,
- rect.size.width);
- tran = CGAffineTransformScale(tran, -1.0, 1.0);
- tran = CGAffineTransformRotate(tran, 3.0 * M_PI / 2.0);
- break;
-
- case UIImageOrientationRight:
- bnds = swapWidthAndHeight(bnds);
- tran = CGAffineTransformMakeTranslation(rect.size.height, 0.0);
- tran = CGAffineTransformRotate(tran, M_PI / 2.0);
- break;
-
- case UIImageOrientationRightMirrored:
- bnds = swapWidthAndHeight(bnds);
- tran = CGAffineTransformMakeScale(-1.0, 1.0);
- tran = CGAffineTransformRotate(tran, M_PI / 2.0);
- break;
-
- default:
- return self;
- }
-
- UIGraphicsBeginImageContext(bnds.size);
- ctxt = UIGraphicsGetCurrentContext();
-
- switch (orient)
- {
- case UIImageOrientationLeft:
- case UIImageOrientationLeftMirrored:
- case UIImageOrientationRight:
- case UIImageOrientationRightMirrored:
- CGContextScaleCTM(ctxt, -1.0, 1.0);
- CGContextTranslateCTM(ctxt, -rect.size.height, 0.0);
- break;
-
- default:
- CGContextScaleCTM(ctxt, 1.0, -1.0);
- CGContextTranslateCTM(ctxt, 0.0, -rect.size.height);
- break;
- }
-
- CGContextConcatCTM(ctxt, tran);
- CGContextDrawImage(UIGraphicsGetCurrentContext(), rect, imag);
-
- copy = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
-
- return copy;
- }
- /** 交换宽和高 */
- static CGRect swapWidthAndHeight(CGRect rect) {
- CGFloat swap = rect.size.width;
-
- rect.size.width = rect.size.height;
- rect.size.height = swap;
-
- return rect;
- }
- + (UIImage *)hx_imageWithColor:(UIColor *)color havingSize:(CGSize)size {
- CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
- UIGraphicsBeginImageContext(rect.size);
- CGContextRef context = UIGraphicsGetCurrentContext();
-
- CGContextSetFillColorWithColor(context, [color CGColor]);
- CGContextFillRect(context, rect);
-
- UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
-
- return image;
- }
- - (UIImage *)hx_cropInRect:(CGRect)rect {
- if (CGPointEqualToPoint(CGPointZero, rect.origin) && CGSizeEqualToSize(self.size, rect.size)) {
- return self;
- }
- UIImage *smallImage = nil;
- CGImageRef sourceImageRef = [self CGImage];
- CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect);
- if (newImageRef) {
- smallImage = [UIImage imageWithCGImage:newImageRef scale:self.scale orientation:self.imageOrientation];
- CGImageRelease(newImageRef);
- }
- return smallImage;
- }
- - (UIImage *)hx_roundClipingImage {
- UIGraphicsBeginImageContext(self.size);
- UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
- [path addClip];
- [self drawAtPoint:CGPointZero];
- UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- return newImage;
- }
- - (UIImage *)hx_scaleToFillSize:(CGSize)size {
- if (CGSizeEqualToSize(self.size, size)) {
- return self;
- }
-
- // 创建一个context
- // 并把它设置成为当前正在使用的context
- UIGraphicsBeginImageContextWithOptions(size, NO, self.scale);
-
- // 绘制改变大小的图片
- [self drawInRect:CGRectMake(0, 0, size.width, size.height)];
-
- // 从当前context中创建一个改变大小后的图片
- UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
-
- // 使当前的context出堆栈
- UIGraphicsEndImageContext();
-
- // 返回新的改变大小后的图片
- return scaledImage;
- }
- /** 合并图片(图片大小一致) */
- - (UIImage *)hx_mergeimages:(NSArray <UIImage *>*)images {
- CGSize size = self.size;
- while (size.width * size.height > 3 * 1000 * 1000) {
- size.width /= 2;
- size.height /= 2;
- }
- UIGraphicsBeginImageContextWithOptions(size ,NO, 0);
- [self drawInRect:CGRectMake(0, 0, size.width, size.height)];
- for (UIImage *image in images) {
- size = image.size;
- while (size.width * size.height > 3 * 1000 * 1000) {
- size.width /= 2;
- size.height /= 2;
- }
- [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
- }
- UIImage *mergeImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- return mergeImage;
- }
- /** 合并图片(图片大小以第一张为准) */
- + (UIImage *)hx_mergeimages:(NSArray <UIImage *>*)images {
- UIGraphicsBeginImageContextWithOptions(images.firstObject.size ,NO, 0);
- for (UIImage *image in images) {
- [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
- }
- UIImage *mergeImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- return mergeImage;
- }
- + (CGSize)hx_scaleImageSizeBySize:(CGSize)imageSize targetSize:(CGSize)size isBoth:(BOOL)isBoth {
-
- /** 原图片大小为0 不再往后处理 */
- if (CGSizeEqualToSize(imageSize, CGSizeZero)) {
- return imageSize;
- }
-
- CGFloat width = imageSize.width;
- CGFloat height = imageSize.height;
- CGFloat targetWidth = size.width;
- CGFloat targetHeight = size.height;
- CGFloat scaleFactor = 0.0;
- CGFloat scaledWidth = targetWidth;
- CGFloat scaledHeight = targetHeight;
- CGPoint thumbnailPoint = CGPointMake(0.0, 0.0);
- if(CGSizeEqualToSize(imageSize, size) == NO){
- CGFloat widthFactor = targetWidth / width;
- CGFloat heightFactor = targetHeight / height;
- if (isBoth) {
- if(widthFactor > heightFactor){
- scaleFactor = widthFactor;
- }
- else{
- scaleFactor = heightFactor;
- }
- } else {
- if(widthFactor > heightFactor){
- scaleFactor = heightFactor;
- }
- else{
- scaleFactor = widthFactor;
- }
- }
- scaledWidth = width * scaleFactor;
- scaledHeight = height * scaleFactor;
- if(widthFactor > heightFactor){
- thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
- }else if(widthFactor < heightFactor){
- thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
- }
- }
- return CGSizeMake(ceilf(scaledWidth), ceilf(scaledHeight));
- }
- - (UIImage*)hx_scaleToFitSize:(CGSize)size {
- if (CGSizeEqualToSize(self.size, size)) {
- return self;
- }
- 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 = roundf(width*radio);
- height = roundf(height*radio);
-
- int xPos = (size.width - width)/2;
- int yPos = (size.height-height)/2;
-
- // 创建一个context
- // 并把它设置成为当前正在使用的context
- UIGraphicsBeginImageContextWithOptions(size, NO, self.scale);
-
- // 绘制改变大小的图片
- [self drawInRect:CGRectMake(xPos, yPos, width, height)];
-
- // 从当前context中创建一个改变大小后的图片
- UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
-
- // 使当前的context出堆栈
- UIGraphicsEndImageContext();
-
- // 返回新的改变大小后的图片
- return scaledImage;
- }
- @end
|