UIImage+Extension.m 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. //
  2. // UIImage+Extension.m
  3. // HuaKaiChat
  4. //
  5. // Created by BigBiao on 2017/9/16.
  6. // Copyright © 2017年 huakai. All rights reserved.
  7. //
  8. #import "UIImage+Extension.h"
  9. #import <AVFoundation/AVFoundation.h>
  10. #import <Accelerate/Accelerate.h>
  11. #import <float.h>
  12. #define AspectRatio 1.0
  13. #define AspectRatioDT 1.0
  14. @implementation UIImage (Extension)
  15. - (UIImage*)imageWithSize:(CGSize)size cornerRadius:(CGFloat)corner rectCornerType:(UIRectCorner)cornerType{
  16. // 传入的View.frame.size是0的话,直接返回nil,防止 UIGraphicsBeginImageContext() 传入0,导致崩溃
  17. if (CGSizeEqualToSize(size, CGSizeZero)) {
  18. return nil;
  19. }
  20. UIGraphicsBeginImageContext(size);
  21. if (!UIGraphicsGetCurrentContext()) {
  22. return nil;
  23. }
  24. UIBezierPath* path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, size.width, size.height) byRoundingCorners:cornerType cornerRadii:CGSizeMake(corner, corner)];
  25. [path addClip];
  26. [(UIImage*)self drawInRect:CGRectMake(0, 0, size.width, size.height)];
  27. UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
  28. UIGraphicsEndImageContext();
  29. return newImage;
  30. }
  31. + (UIImage *)screenshot
  32. {
  33. CGSize imageSize = [[UIScreen mainScreen] bounds].size;
  34. // 传入的View.frame.size是0的话,直接返回nil,防止 UIGraphicsBeginImageContext() 传入0,导致崩溃
  35. if (CGSizeEqualToSize(imageSize, CGSizeZero)) {
  36. return nil;
  37. }
  38. if (NULL != UIGraphicsBeginImageContextWithOptions) {
  39. UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
  40. } else {
  41. UIGraphicsBeginImageContext(imageSize);
  42. }
  43. CGContextRef context = UIGraphicsGetCurrentContext();
  44. for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
  45. if (![window respondsToSelector:@selector(screen)] || [window screen] == [UIScreen mainScreen]) {
  46. CGContextSaveGState(context);
  47. CGContextTranslateCTM(context, [window center].x, [window center].y);
  48. CGContextConcatCTM(context, [window transform]);
  49. CGContextTranslateCTM(context,
  50. -[window bounds].size.width * [[window layer] anchorPoint].x,
  51. -[window bounds].size.height * [[window layer] anchorPoint].y);
  52. [[window layer] renderInContext:context];
  53. CGContextRestoreGState(context);
  54. }
  55. }
  56. UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  57. UIGraphicsEndImageContext();
  58. return image;
  59. }
  60. + (UIImage *)cutImage:(UIImage*)image isDT:(BOOL)flag
  61. {
  62. //压缩图片
  63. CGSize newSize;
  64. CGFloat padHeight;
  65. CGImageRef imageRef = nil;
  66. newSize.width = image.size.width;
  67. if (flag) {
  68. newSize.height = newSize.width*AspectRatioDT;
  69. padHeight = (image.size.height-image.size.width*AspectRatioDT)/2;
  70. }else{
  71. newSize.height = newSize.width*AspectRatio;
  72. padHeight = (image.size.height-image.size.width*AspectRatio)/2;
  73. }
  74. imageRef = CGImageCreateWithImageInRect([image CGImage], CGRectMake(0, padHeight, newSize.width, newSize.height));
  75. return [UIImage imageWithCGImage:imageRef];
  76. }
  77. + (UIImage *)imageWithVideo:(NSURL *)videoURL
  78. {
  79. AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
  80. AVAssetImageGenerator* gen = [[AVAssetImageGenerator alloc] initWithAsset: asset];
  81. gen.appliesPreferredTrackTransform = YES;
  82. gen.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;
  83. CMTime time = CMTimeMake(0, 2);
  84. NSError *error = nil;
  85. CMTime actualTime;
  86. CGImageRef image = [gen copyCGImageAtTime: time actualTime: &actualTime error:&error];
  87. UIImage *thumb = [[UIImage alloc] initWithCGImage: image];
  88. CGImageRelease(image);
  89. return thumb;
  90. }
  91. + (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size
  92. {
  93. CGRect rect = CGRectMake(0, 0, size.width, size.height);
  94. // 传入的View.frame.size是0的话,直接返回nil,防止 UIGraphicsBeginImageContext() 传入0,导致崩溃
  95. if (CGSizeEqualToSize(rect.size, CGSizeZero)) {
  96. return nil;
  97. }
  98. UIGraphicsBeginImageContext(rect.size);
  99. CGContextRef context = UIGraphicsGetCurrentContext();
  100. CGContextSetFillColorWithColor(context,color.CGColor);
  101. CGContextFillRect(context, rect);
  102. UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
  103. UIGraphicsEndImageContext();
  104. return img;
  105. }
  106. - (UIImage *)imageByApplyingAlpha:(CGFloat)alpha{
  107. // 传入的View.frame.size是0的话,直接返回nil,防止 UIGraphicsBeginImageContext() 传入0,导致崩溃
  108. if (CGSizeEqualToSize(self.size, CGSizeZero)) {
  109. return nil;
  110. }
  111. UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
  112. CGContextRef ctx = UIGraphicsGetCurrentContext();
  113. CGRect area = CGRectMake(0, 0, self.size.width, self.size.height);
  114. CGContextScaleCTM(ctx, 1, -1);
  115. CGContextTranslateCTM(ctx, 0, -area.size.height);
  116. CGContextSetBlendMode(ctx, kCGBlendModeMultiply);
  117. CGContextSetAlpha(ctx, alpha);
  118. CGContextDrawImage(ctx, area, self.CGImage);
  119. UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  120. UIGraphicsEndImageContext();
  121. return newImage;
  122. }
  123. + (instancetype)waterImageWithBg:(UIImage*)bgImg centerImg:(NSString *)centerImg
  124. {
  125. UIGraphicsBeginImageContextWithOptions(CGSizeMake((KScreenWidth-20)/2, (KScreenWidth-20)/2), NO, 0.0);
  126. [bgImg drawInRect:CGRectMake(0, 0,(KScreenWidth-20)/2, (KScreenWidth-20)/2)];
  127. //要绘制的内容
  128. //1.绘制灰色背景
  129. UIImage* grayImage = [UIImage imageWithColor:DecColorFromRGBA(0, 0, 0,0) size:bgImg.size];
  130. [grayImage drawInRect:CGRectMake(0, 0, (KScreenWidth-20)/2, (KScreenWidth-20)/2)];
  131. //2.绘制文字
  132. // NSString* str =@"免费现场预览";
  133. // [str drawInRect:CGRectMake(KScreenWidth/3,KScreenWidth*AspectRatio/2-10 ,KScreenWidth/3-30, 40) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15],NSForegroundColorAttributeName:[UIColor whiteColor]}];
  134. //3.绘制播放按钮
  135. UIImage* img = [[UIImage imageNamed:centerImg] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
  136. // [img drawInRect:CGRectMake((KScreenWidth-img.size.width)/2,KScreenWidth*AspectRatio/2-15,img.size.width,img.size.height )];
  137. [img drawAtPoint:CGPointMake((KScreenWidth-20)/4-img.size.width/2, (KScreenWidth-20)/4-img.size.height/2)];
  138. // [img drawInRect:CGRectMake(0, 0, img.size.width, img.size.height)];
  139. UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  140. UIGraphicsEndImageContext();
  141. return newImage;
  142. }
  143. + (UIImage*)screenView:(UIView *)view{
  144. CGRect rect = view.frame;
  145. // 传入的View.frame.size是0的话,直接返回nil,防止 UIGraphicsBeginImageContext() 传入0,导致崩溃
  146. if (CGSizeEqualToSize(rect.size, CGSizeZero)) {
  147. return nil;
  148. }
  149. UIGraphicsBeginImageContext(rect.size);
  150. CGContextRef context = UIGraphicsGetCurrentContext();
  151. [view.layer renderInContext:context];
  152. //add by leo
  153. [view drawViewHierarchyInRect: view.frame afterScreenUpdates:YES];
  154. UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
  155. UIGraphicsEndImageContext();
  156. return img;
  157. }
  158. //图片压缩到指定大小1280*1280内
  159. - (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize
  160. {
  161. UIImage *sourceImage = self;
  162. UIImage *newImage = nil;
  163. CGSize imageSize = sourceImage.size;
  164. CGFloat width = imageSize.width;
  165. CGFloat height = imageSize.height;
  166. CGFloat targetWidth = targetSize.width;
  167. CGFloat targetHeight = targetSize.height;
  168. CGFloat scaleFactor = 0.0;
  169. CGFloat scaledWidth = targetWidth;
  170. CGFloat scaledHeight = targetHeight;
  171. CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
  172. if (CGSizeEqualToSize(imageSize, targetSize) == NO)
  173. {
  174. CGFloat widthFactor = targetWidth / width;
  175. CGFloat heightFactor = targetHeight / height;
  176. if (widthFactor > heightFactor)
  177. scaleFactor = widthFactor; // scale to fit height
  178. else
  179. scaleFactor = heightFactor; // scale to fit width
  180. scaledWidth= width * scaleFactor;
  181. scaledHeight = height * scaleFactor;
  182. // center the image
  183. if (widthFactor > heightFactor)
  184. {
  185. thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
  186. }
  187. else if (widthFactor < heightFactor)
  188. {
  189. thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
  190. }
  191. }
  192. // 传入的View.frame.size是0的话,直接返回nil,防止 UIGraphicsBeginImageContext() 传入0,导致崩溃
  193. if (CGSizeEqualToSize(targetSize, CGSizeZero)) {
  194. return nil;
  195. }
  196. UIGraphicsBeginImageContext(targetSize); // this will crop
  197. CGRect thumbnailRect = CGRectZero;
  198. thumbnailRect.origin = thumbnailPoint;
  199. thumbnailRect.size.width= scaledWidth;
  200. thumbnailRect.size.height = scaledHeight;
  201. [sourceImage drawInRect:thumbnailRect];
  202. newImage = UIGraphicsGetImageFromCurrentImageContext();
  203. if(newImage == nil)
  204. NSLog(@"could not scale image");
  205. //pop the context to get back to the default
  206. UIGraphicsEndImageContext();
  207. return newImage;
  208. }
  209. //循环压缩图片到制定大小
  210. //循环压缩图片到制定大小
  211. - (NSData *)compressImageToMaxFileSize:(NSInteger)maxFileSize {
  212. CGFloat compression = 1.0f;
  213. CGFloat maxCompression = 0.01f;
  214. NSData *imageData = UIImageJPEGRepresentation(self, compression);
  215. NSLog(@"%lu",imageData.length);
  216. while ([imageData length] > maxFileSize && compression > maxCompression) {
  217. compression -= 0.01;
  218. imageData = UIImageJPEGRepresentation(self, compression);
  219. }
  220. return imageData;
  221. }
  222. + (NSData *)zipGiFWithAsset:(PHAsset*)asset{
  223. NSArray *resourceList = [PHAssetResource assetResourcesForAsset:asset];
  224. [resourceList enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  225. PHAssetResource *resource = obj;
  226. PHAssetResourceRequestOptions *option = [[PHAssetResourceRequestOptions alloc]init];
  227. option.networkAccessAllowed = YES;
  228. if ([resource.uniformTypeIdentifier isEqualToString:@"com.compuserve.gif"]) {
  229. NSLog(@"gif大爷");
  230. // 首先,需要获取沙盒路径
  231. NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
  232. // 拼接图片名为resource.originalFilename的路径
  233. NSString *imageFilePath = [path stringByAppendingPathComponent:resource.originalFilename];
  234. __block NSData *data = [[NSData alloc]init];
  235. [[PHAssetResourceManager defaultManager] writeDataForAssetResource:resource toFile:[NSURL fileURLWithPath:imageFilePath] options:option completionHandler:^(NSError * _Nullable error) {
  236. if (error) {
  237. NSLog(@"error:%@",error);
  238. if(error.code == -1){//文件已存在
  239. data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:imageFilePath]];
  240. }
  241. //NSLog(@"data%@",data);
  242. } else {
  243. data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:imageFilePath]];
  244. //NSLog(@"data%@",data);
  245. }
  246. }];
  247. }else{
  248. NSLog(@"jepg大爷");
  249. }
  250. }];
  251. return nil;
  252. }
  253. + (NSData *)zipGIFWithData:(NSData *)data {
  254. // if (!data) {
  255. // return nil;
  256. // }
  257. // CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
  258. // size_t count = CGImageSourceGetCount(source);
  259. // UIImage *animatedImage = nil;
  260. // NSMutableArray *images = [NSMutableArray array];
  261. // NSTimeInterval duration = 0.0f;
  262. // for (size_t i = 0; i < count; i++) {
  263. // CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
  264. // duration += [self frameDurationAtIndex:i source:source];
  265. // UIImage *ima = [UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
  266. // ima = [ima zip];
  267. // [images addObject:ima];
  268. // CGImageRelease(image);
  269. // if (!duration) {
  270. // duration = (1.0f / 10.0f) * count;
  271. // }
  272. // animatedImage = [UIImage animatedImageWithImages:images duration:duration];
  273. // }
  274. // CFRelease(source);
  275. // return UIImagePNGRepresentation(animatedImage);
  276. return nil;
  277. }
  278. +(NSData *)zipNSDataWithImage:(UIImage *)sourceImage maxFileSize:(NSInteger)maxFileSize {
  279. //进行图像尺寸的压缩
  280. CGSize imageSize = sourceImage.size;//取出要压缩的image尺寸
  281. CGFloat width = imageSize.width; //图片宽度
  282. CGFloat height = imageSize.height; //图片高度
  283. //1.宽高大于1280(宽高比不按照2来算,按照1来算)
  284. if (width>1280) {
  285. if (width>height) {
  286. CGFloat scale = width/height;
  287. height = 1280;
  288. width = height*scale;
  289. }else{
  290. CGFloat scale = height/width;
  291. width = 1280;
  292. height = width*scale;
  293. }
  294. //2.高度大于1280
  295. }else if(height>1280){
  296. CGFloat scale = height/width;
  297. width = 1280;
  298. height = width*scale;
  299. }else{
  300. }
  301. // 传入的View.frame.size是0的话,直接返回nil,防止 UIGraphicsBeginImageContext() 传入0,导致崩溃
  302. if (CGSizeEqualToSize(imageSize, CGSizeZero)) {
  303. return nil;
  304. }
  305. UIGraphicsBeginImageContext(CGSizeMake(width, height));
  306. if (sourceImage) {
  307. [sourceImage drawInRect:CGRectMake(0,0,width,height)];
  308. }
  309. UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
  310. UIGraphicsEndImageContext();
  311. return [newImage compressImageToMaxFileSize:maxFileSize];//200KB
  312. }
  313. @end
  314. @implementation UIImage (ImageEffects)
  315. - (UIImage *)applyLightEffect
  316. {
  317. UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3];
  318. return [self applyBlurWithRadius:30 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
  319. }
  320. - (UIImage *)applyExtraLightEffect
  321. {
  322. UIColor *tintColor = [UIColor colorWithWhite:0.97 alpha:0.82];
  323. return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
  324. }
  325. - (UIImage *)applyDarkEffect
  326. {
  327. UIColor *tintColor = DecColorFromRGBA(79, 66, 81, 0.8);
  328. return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
  329. }
  330. - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor
  331. {
  332. const CGFloat EffectColorAlpha = 0.6;
  333. UIColor *effectColor = tintColor;
  334. long int componentCount = CGColorGetNumberOfComponents(tintColor.CGColor);
  335. if (componentCount == 2) {
  336. CGFloat b;
  337. if ([tintColor getWhite:&b alpha:NULL]) {
  338. effectColor = [UIColor colorWithWhite:b alpha:EffectColorAlpha];
  339. }
  340. }
  341. else {
  342. CGFloat r, g, b;
  343. if ([tintColor getRed:&r green:&g blue:&b alpha:NULL]) {
  344. effectColor = [UIColor colorWithRed:r green:g blue:b alpha:EffectColorAlpha];
  345. }
  346. }
  347. return [self applyBlurWithRadius:10 tintColor:effectColor saturationDeltaFactor:-1.0 maskImage:nil];
  348. }
  349. - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage
  350. {
  351. // Check pre-conditions.
  352. if (self.size.width < 1 || self.size.height < 1) {
  353. NSLog (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self);
  354. return nil;
  355. }
  356. if (!self.CGImage) {
  357. NSLog (@"*** error: image must be backed by a CGImage: %@", self);
  358. return nil;
  359. }
  360. if (maskImage && !maskImage.CGImage) {
  361. NSLog (@"*** error: maskImage must be backed by a CGImage: %@", maskImage);
  362. return nil;
  363. }
  364. CGRect imageRect = { CGPointZero, self.size };
  365. UIImage *effectImage = self;
  366. BOOL hasBlur = blurRadius > __FLT_EPSILON__;
  367. BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__;
  368. if (hasBlur || hasSaturationChange) {
  369. // 传入的View.frame.size是0的话,直接返回nil,防止 UIGraphicsBeginImageContext() 传入0,导致崩溃
  370. if (CGSizeEqualToSize(self.size, CGSizeZero)) {
  371. return nil;
  372. }
  373. UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
  374. CGContextRef effectInContext = UIGraphicsGetCurrentContext();
  375. CGContextScaleCTM(effectInContext, 1.0, -1.0);
  376. CGContextTranslateCTM(effectInContext, 0, -self.size.height);
  377. CGContextDrawImage(effectInContext, imageRect, self.CGImage);
  378. vImage_Buffer effectInBuffer;
  379. effectInBuffer.data = CGBitmapContextGetData(effectInContext);
  380. effectInBuffer.width = CGBitmapContextGetWidth(effectInContext);
  381. effectInBuffer.height = CGBitmapContextGetHeight(effectInContext);
  382. effectInBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectInContext);
  383. UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
  384. CGContextRef effectOutContext = UIGraphicsGetCurrentContext();
  385. vImage_Buffer effectOutBuffer;
  386. effectOutBuffer.data = CGBitmapContextGetData(effectOutContext);
  387. effectOutBuffer.width = CGBitmapContextGetWidth(effectOutContext);
  388. effectOutBuffer.height = CGBitmapContextGetHeight(effectOutContext);
  389. effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext);
  390. if (hasBlur) {
  391. // A description of how to compute the box kernel width from the Gaussian
  392. // radius (aka standard deviation) appears in the SVG spec:
  393. // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement
  394. //
  395. // For larger values of 's' (s >= 2.0), an approximation can be used: Three
  396. // successive box-blurs build a piece-wise quadratic convolution kernel, which
  397. // approximates the Gaussian kernel to within roughly 3%.
  398. //
  399. // let d = floor(s * 3*sqrt(2*pi)/4 + 0.5)
  400. //
  401. // ... if d is odd, use three box-blurs of size 'd', centered on the output pixel.
  402. //
  403. CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale];
  404. int radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5);
  405. if (radius % 2 != 1) {
  406. radius += 1; // force radius to be odd so that the three box-blur methodology works.
  407. }
  408. vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
  409. vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
  410. vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
  411. }
  412. BOOL effectImageBuffersAreSwapped = NO;
  413. if (hasSaturationChange) {
  414. CGFloat s = saturationDeltaFactor;
  415. CGFloat floatingPointSaturationMatrix[] = {
  416. 0.0722 + 0.9278 * s, 0.0722 - 0.0722 * s, 0.0722 - 0.0722 * s, 0,
  417. 0.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s, 0,
  418. 0.2126 - 0.2126 * s, 0.2126 - 0.2126 * s, 0.2126 + 0.7873 * s, 0,
  419. 0, 0, 0, 1,
  420. };
  421. const int32_t divisor = 256;
  422. NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]);
  423. int16_t saturationMatrix[matrixSize];
  424. for (NSUInteger i = 0; i < matrixSize; ++i) {
  425. saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor);
  426. }
  427. if (hasBlur) {
  428. vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);
  429. effectImageBuffersAreSwapped = YES;
  430. }
  431. else {
  432. vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);
  433. }
  434. }
  435. if (!effectImageBuffersAreSwapped)
  436. effectImage = UIGraphicsGetImageFromCurrentImageContext();
  437. UIGraphicsEndImageContext();
  438. if (effectImageBuffersAreSwapped)
  439. effectImage = UIGraphicsGetImageFromCurrentImageContext();
  440. UIGraphicsEndImageContext();
  441. }
  442. // 传入的View.frame.size是0的话,直接返回nil,防止 UIGraphicsBeginImageContext() 传入0,导致崩溃
  443. if (CGSizeEqualToSize(self.size, CGSizeZero)) {
  444. return nil;
  445. }
  446. // Set up output context.
  447. UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
  448. CGContextRef outputContext = UIGraphicsGetCurrentContext();
  449. CGContextScaleCTM(outputContext, 1.0, -1.0);
  450. CGContextTranslateCTM(outputContext, 0, -self.size.height);
  451. // Draw base image.
  452. CGContextDrawImage(outputContext, imageRect, self.CGImage);
  453. // Draw effect image.
  454. if (hasBlur) {
  455. CGContextSaveGState(outputContext);
  456. if (maskImage) {
  457. CGContextClipToMask(outputContext, imageRect, maskImage.CGImage);
  458. }
  459. CGContextDrawImage(outputContext, imageRect, effectImage.CGImage);
  460. CGContextRestoreGState(outputContext);
  461. }
  462. // Add in color tint.
  463. if (tintColor) {
  464. CGContextSaveGState(outputContext);
  465. CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);
  466. CGContextFillRect(outputContext, imageRect);
  467. CGContextRestoreGState(outputContext);
  468. }
  469. // Output image is ready.
  470. UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
  471. UIGraphicsEndImageContext();
  472. return outputImage;
  473. }
  474. + (UIImage *)imageWithScreenshot
  475. {
  476. NSData *imageData = [self dataWithScreenshotInPNGFormat];
  477. return [UIImage imageWithData:imageData];
  478. }
  479. + (NSData *)dataWithScreenshotInPNGFormat
  480. {
  481. CGSize imageSize = CGSizeZero;
  482. UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
  483. if (UIInterfaceOrientationIsPortrait(orientation))
  484. imageSize = [UIScreen mainScreen].bounds.size;
  485. else
  486. imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
  487. // 传入的View.frame.size是0的话,直接返回nil,防止 UIGraphicsBeginImageContext() 传入0,导致崩溃
  488. if (CGSizeEqualToSize(imageSize, CGSizeZero)) {
  489. return nil;
  490. }
  491. UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
  492. CGContextRef context = UIGraphicsGetCurrentContext();
  493. for (UIWindow *window in [[UIApplication sharedApplication] windows])
  494. {
  495. CGContextSaveGState(context);
  496. CGContextTranslateCTM(context, window.center.x, window.center.y);
  497. CGContextConcatCTM(context, window.transform);
  498. CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y);
  499. if (orientation == UIInterfaceOrientationLandscapeLeft)
  500. {
  501. CGContextRotateCTM(context, M_PI_2);
  502. CGContextTranslateCTM(context, 0, -imageSize.width);
  503. }
  504. else if (orientation == UIInterfaceOrientationLandscapeRight)
  505. {
  506. CGContextRotateCTM(context, -M_PI_2);
  507. CGContextTranslateCTM(context, -imageSize.height, 0);
  508. } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
  509. CGContextRotateCTM(context, M_PI);
  510. CGContextTranslateCTM(context, -imageSize.width, -imageSize.height);
  511. }
  512. if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)])
  513. {
  514. [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];
  515. }
  516. else
  517. {
  518. [window.layer renderInContext:context];
  519. }
  520. CGContextRestoreGState(context);
  521. }
  522. UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  523. UIGraphicsEndImageContext();
  524. return UIImagePNGRepresentation(image);
  525. }
  526. - (UIImage *)cutCircleImage {
  527. // 传入的View.frame.size是0的话,直接返回nil,防止 UIGraphicsBeginImageContext() 传入0,导致崩溃
  528. if (CGSizeEqualToSize(self.size, CGSizeZero)) {
  529. return nil;
  530. }
  531. //开始图片上下文
  532. UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0);
  533. // 获取上下文
  534. CGContextRef ctr = UIGraphicsGetCurrentContext();
  535. // 设置圆形
  536. CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
  537. CGContextAddEllipseInRect(ctr, rect);
  538. // 裁剪
  539. CGContextClip(ctr);
  540. // 将图片画上去
  541. [self drawInRect:rect];
  542. UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  543. UIGraphicsEndImageContext();
  544. return image;
  545. }
  546. +(UIImage *)boxblurImage:(UIImage *)image withBlurNumber:(CGFloat)blur {
  547. if (blur < 0.f || blur > 1.f) {
  548. blur = 0.5f;
  549. }
  550. int boxSize = (int)(blur * 40);
  551. boxSize = boxSize - (boxSize % 2) + 1;
  552. CGImageRef img = image.CGImage;
  553. vImage_Buffer inBuffer, outBuffer;
  554. vImage_Error error;
  555. void *pixelBuffer;
  556. //从CGImage中获取数据
  557. CGDataProviderRef inProvider = CGImageGetDataProvider(img);
  558. CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
  559. //设置从CGImage获取对象的属性
  560. inBuffer.width = CGImageGetWidth(img);
  561. inBuffer.height = CGImageGetHeight(img);
  562. inBuffer.rowBytes = CGImageGetBytesPerRow(img);
  563. inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);
  564. pixelBuffer = malloc(CGImageGetBytesPerRow(img) *
  565. CGImageGetHeight(img));
  566. if(pixelBuffer == NULL)
  567. NSLog(@"No pixelbuffer");
  568. outBuffer.data = pixelBuffer;
  569. outBuffer.width = CGImageGetWidth(img);
  570. outBuffer.height = CGImageGetHeight(img);
  571. outBuffer.rowBytes = CGImageGetBytesPerRow(img);
  572. error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
  573. if (error) {
  574. NSLog(@"error from convolution %ld", error);
  575. }
  576. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  577. CGContextRef ctx = CGBitmapContextCreate(
  578. outBuffer.data,
  579. outBuffer.width,
  580. outBuffer.height,
  581. 8,
  582. outBuffer.rowBytes,
  583. colorSpace,
  584. kCGImageAlphaNoneSkipLast);
  585. CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
  586. UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
  587. //clean up
  588. CGContextRelease(ctx);
  589. CGColorSpaceRelease(colorSpace);
  590. free(pixelBuffer);
  591. CFRelease(inBitmapData);
  592. CGColorSpaceRelease(colorSpace);
  593. CGImageRelease(imageRef);
  594. return returnImage;
  595. }
  596. @end