UIImage+RQExtension.m 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. //
  2. // UIImage+RQExtension.m
  3. // RQCommon
  4. //
  5. // Created by 张嵘 on 2018/11/16.
  6. // Copyright © 2018 张嵘. All rights reserved.
  7. //
  8. #import "UIImage+RQExtension.h"
  9. #import <AVFoundation/AVFoundation.h>
  10. #import <AssetsLibrary/AssetsLibrary.h>
  11. @implementation UIImage (RQExtension)
  12. /**
  13. * 根据图片名返回一张能够自由拉伸的图片 (从中间拉伸)
  14. */
  15. + (UIImage *)rq_resizableImage:(NSString *)imgName
  16. {
  17. UIImage *image = [UIImage imageNamed:imgName];
  18. return [self rq_resizableImage:imgName capInsets:UIEdgeInsetsMake(image.size.height *.5f, image.size.width*.5f, image.size.height*.5f, image.size.width*.5f)];
  19. }
  20. + (UIImage *)rq_resizableImage:(NSString *)imgName capInsets:(UIEdgeInsets)capInsets
  21. {
  22. UIImage *image = [UIImage imageNamed:imgName];
  23. return [image resizableImageWithCapInsets:capInsets];
  24. }
  25. + (UIImage *)rq_imageAlwaysShowOriginalImageWithImageName:(NSString *)imageName
  26. {
  27. UIImage *image = [UIImage imageNamed:imageName];
  28. if ([image respondsToSelector:@selector(imageWithRenderingMode:)])
  29. { //iOS 7.0+
  30. return [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
  31. }else{
  32. return image;
  33. }
  34. }
  35. + (UIImage*)rq_thumbnailImageForVideo:(NSURL *)videoURL atTime:(NSTimeInterval)time {
  36. AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
  37. NSParameterAssert(asset);
  38. AVAssetImageGenerator *assetImageGenerator =[[AVAssetImageGenerator alloc] initWithAsset:asset];
  39. assetImageGenerator.appliesPreferredTrackTransform = YES;
  40. assetImageGenerator.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;
  41. CGImageRef thumbnailImageRef = NULL;
  42. CFTimeInterval thumbnailImageTime = time;
  43. NSError *thumbnailImageGenerationError = nil;
  44. thumbnailImageRef = [assetImageGenerator copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60)actualTime:NULL error:&thumbnailImageGenerationError];
  45. if(!thumbnailImageRef)
  46. NSLog(@"thumbnailImageGenerationError %@",thumbnailImageGenerationError);
  47. UIImage*thumbnailImage = thumbnailImageRef ? [[UIImage alloc]initWithCGImage: thumbnailImageRef] : nil;
  48. return thumbnailImage;
  49. }
  50. /// 获取屏幕截图
  51. ///
  52. /// @return 屏幕截图图像
  53. + (UIImage *)rq_screenShot {
  54. // 1. 获取到窗口
  55. UIWindow *window = [UIApplication sharedApplication].keyWindow;
  56. // 2. 开始上下文
  57. UIGraphicsBeginImageContextWithOptions(window.bounds.size, YES, 0);
  58. // 3. 将 window 中的内容绘制输出到当前上下文
  59. [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:NO];
  60. // 4. 获取图片
  61. UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
  62. // 5. 关闭上下文
  63. UIGraphicsEndImageContext();
  64. return screenShot;
  65. }
  66. - (UIImage *)rq_fixOrientation {
  67. // No-op if the orientation is already correct
  68. if (self.imageOrientation == UIImageOrientationUp) return self;
  69. // We need to calculate the proper transformation to make the image upright.
  70. // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
  71. CGAffineTransform transform = CGAffineTransformIdentity;
  72. switch (self.imageOrientation) {
  73. case UIImageOrientationDown:
  74. case UIImageOrientationDownMirrored:
  75. transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
  76. transform = CGAffineTransformRotate(transform, M_PI);
  77. break;
  78. case UIImageOrientationLeft:
  79. case UIImageOrientationLeftMirrored:
  80. transform = CGAffineTransformTranslate(transform, self.size.width, 0);
  81. transform = CGAffineTransformRotate(transform, M_PI_2);
  82. break;
  83. case UIImageOrientationRight:
  84. case UIImageOrientationRightMirrored:
  85. transform = CGAffineTransformTranslate(transform, 0, self.size.height);
  86. transform = CGAffineTransformRotate(transform, -M_PI_2);
  87. break;
  88. case UIImageOrientationUp:
  89. case UIImageOrientationUpMirrored:
  90. break;
  91. }
  92. switch (self.imageOrientation) {
  93. case UIImageOrientationUpMirrored:
  94. case UIImageOrientationDownMirrored:
  95. transform = CGAffineTransformTranslate(transform, self.size.width, 0);
  96. transform = CGAffineTransformScale(transform, -1, 1);
  97. break;
  98. case UIImageOrientationLeftMirrored:
  99. case UIImageOrientationRightMirrored:
  100. transform = CGAffineTransformTranslate(transform, self.size.height, 0);
  101. transform = CGAffineTransformScale(transform, -1, 1);
  102. break;
  103. case UIImageOrientationUp:
  104. case UIImageOrientationDown:
  105. case UIImageOrientationLeft:
  106. case UIImageOrientationRight:
  107. break;
  108. }
  109. // Now we draw the underlying CGImage into a new context, applying the transform
  110. // calculated above.
  111. CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
  112. CGImageGetBitsPerComponent(self.CGImage), 0,
  113. CGImageGetColorSpace(self.CGImage),
  114. CGImageGetBitmapInfo(self.CGImage));
  115. CGContextConcatCTM(ctx, transform);
  116. switch (self.imageOrientation) {
  117. case UIImageOrientationLeft:
  118. case UIImageOrientationLeftMirrored:
  119. case UIImageOrientationRight:
  120. case UIImageOrientationRightMirrored:
  121. // Grr...
  122. CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
  123. break;
  124. default:
  125. CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
  126. break;
  127. }
  128. // And now we just create a new UIImage from the drawing context
  129. CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
  130. UIImage *img = [UIImage imageWithCGImage:cgimg];
  131. CGContextRelease(ctx);
  132. CGImageRelease(cgimg);
  133. return img;
  134. }
  135. //将JPEG格式转换为PNG
  136. -(UIImage *)reduceImage:(UIImage *)image percent:(float)percent
  137. {
  138. NSData *imageData = UIImageJPEGRepresentation(image, percent);
  139. UIImage *newImage = [UIImage imageWithData:imageData];
  140. return newImage;
  141. }
  142. //压缩图片尺寸
  143. - (UIImage *)scaledToSize:(CGSize)newSize
  144. {
  145. //首先要找到缩放比 按长的适配 不足的部分空白
  146. CGFloat rate =newSize.width*1.0/ self.size.width ;
  147. if (self.size.height* rate > newSize.height) {
  148. //过长了。
  149. rate =newSize.height*1.0/ self.size.height ;
  150. }
  151. CGSize size = CGSizeMake(self.size.width*rate, self.size.height*rate);
  152. // Create a graphics image context
  153. UIGraphicsBeginImageContext(size);
  154. // new size
  155. [self drawInRect:CGRectMake(0,0,size.width,size.height)];
  156. // Get the new image from the context
  157. UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
  158. // End the context
  159. UIGraphicsEndImageContext();
  160. // Return the new image.
  161. return newImage;
  162. }
  163. - (UIImage *)scaledAndCutToSize:(CGSize)newSize{
  164. //首先要找到缩放比 按短的适配 长的部分裁减掉
  165. CGFloat rate =newSize.width*1.0/ self.size.width ;
  166. if (self.size.height* rate < newSize.height) {
  167. //过长了。
  168. rate =newSize.height*1.0/ self.size.height ;
  169. }
  170. CGSize size = CGSizeMake(self.size.width*rate, self.size.height*rate);
  171. UIGraphicsBeginImageContext(size);
  172. [self drawInRect:CGRectMake(0,0,size.width,size.height)];
  173. // Get the new image from the context
  174. UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
  175. // End the context
  176. UIGraphicsEndImageContext();
  177. // Return the new image.
  178. return newImage;
  179. }
  180. - (UIImage*)imageRotatedByDegrees:(CGFloat)degrees
  181. {
  182. CGFloat width = CGImageGetWidth(self.CGImage);
  183. CGFloat height = CGImageGetHeight(self.CGImage);
  184. CGSize rotatedSize;
  185. rotatedSize.width = width;
  186. rotatedSize.height = height;
  187. UIGraphicsBeginImageContext(rotatedSize);
  188. CGContextRef bitmap = UIGraphicsGetCurrentContext();
  189. CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);
  190. CGContextRotateCTM(bitmap, degrees * M_PI / 180);
  191. CGContextRotateCTM(bitmap, M_PI);
  192. CGContextScaleCTM(bitmap, -1.0, 1.0);
  193. CGContextDrawImage(bitmap, CGRectMake(-rotatedSize.width/2, -rotatedSize.height/2, rotatedSize.width, rotatedSize.height), self.CGImage);
  194. UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
  195. UIGraphicsEndImageContext();
  196. return newImage;
  197. }
  198. #pragma mark - 压缩图片到指定大小(单位KB)
  199. + (NSData *)resetSizeOfImageData:(UIImage *)sourceImage maxSize:(NSInteger)maxSize {
  200. //先判断当前质量是否满足要求,不满足再进行压缩
  201. __block NSData *finallImageData = UIImageJPEGRepresentation(sourceImage,1.0);
  202. NSUInteger sizeOrigin = finallImageData.length;
  203. NSUInteger sizeOriginKB = sizeOrigin / 1000;
  204. if (sizeOriginKB <= maxSize) {
  205. return finallImageData;
  206. }
  207. //获取原图片宽高比
  208. CGFloat sourceImageAspectRatio = sourceImage.size.width/sourceImage.size.height;
  209. //先调整分辨率
  210. CGSize defaultSize = CGSizeMake(1024, 1024/sourceImageAspectRatio);
  211. UIImage *newImage = [self newSizeImage:defaultSize image:sourceImage];
  212. finallImageData = UIImageJPEGRepresentation(newImage,1.0);
  213. //保存压缩系数
  214. NSMutableArray *compressionQualityArr = [NSMutableArray array];
  215. CGFloat avg = 1.0/250;
  216. CGFloat value = avg;
  217. for (int i = 250; i >= 1; i--) {
  218. value = i*avg;
  219. [compressionQualityArr addObject:@(value)];
  220. }
  221. /*
  222. 调整大小
  223. 说明:压缩系数数组compressionQualityArr是从大到小存储。
  224. */
  225. //思路:使用二分法搜索
  226. __block NSData *canCompressMinData = [NSData data];//当无法压缩到指定大小时,用于存储当前能够压缩到的最小值数据。
  227. [self halfFuntion:compressionQualityArr image:newImage sourceData:finallImageData maxSize:maxSize resultBlock:^(NSData *finallData, NSData *tempData) {
  228. finallImageData = finallData;
  229. canCompressMinData = tempData;
  230. }];
  231. //如果还是未能压缩到指定大小,则进行降分辨率
  232. while (finallImageData.length == 0) {
  233. //每次降100分辨率
  234. CGFloat reduceWidth = 100.0;
  235. CGFloat reduceHeight = 100.0/sourceImageAspectRatio;
  236. if (defaultSize.width-reduceWidth <= 0 || defaultSize.height-reduceHeight <= 0) {
  237. break;
  238. }
  239. defaultSize = CGSizeMake(defaultSize.width-reduceWidth, defaultSize.height-reduceHeight);
  240. UIImage *image = [self newSizeImage:defaultSize
  241. image:[UIImage imageWithData:UIImageJPEGRepresentation(newImage,[[compressionQualityArr lastObject] floatValue])]];
  242. [self halfFuntion:compressionQualityArr image:image sourceData:UIImageJPEGRepresentation(image,1.0) maxSize:maxSize resultBlock:^(NSData *finallData, NSData *tempData) {
  243. finallImageData = finallData;
  244. canCompressMinData = tempData;
  245. }];
  246. }
  247. //如果分辨率已经无法再降低,则直接使用能够压缩的那个最小值即可
  248. if (finallImageData.length==0) {
  249. finallImageData = canCompressMinData;
  250. }
  251. return finallImageData;
  252. }
  253. #pragma mark 调整图片分辨率/尺寸(等比例缩放)
  254. ///调整图片分辨率/尺寸(等比例缩放)
  255. + (UIImage *)newSizeImage:(CGSize)size image:(UIImage *)sourceImage {
  256. CGSize newSize = CGSizeMake(sourceImage.size.width, sourceImage.size.height);
  257. CGFloat tempHeight = newSize.height / size.height;
  258. CGFloat tempWidth = newSize.width / size.width;
  259. if (tempWidth > 1.0 && tempWidth > tempHeight) {
  260. newSize = CGSizeMake(sourceImage.size.width / tempWidth, sourceImage.size.height / tempWidth);
  261. } else if (tempHeight > 1.0 && tempWidth < tempHeight) {
  262. newSize = CGSizeMake(sourceImage.size.width / tempHeight, sourceImage.size.height / tempHeight);
  263. }
  264. // UIGraphicsBeginImageContext(newSize);
  265. UIGraphicsBeginImageContextWithOptions(newSize, NO, 1);
  266. [sourceImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
  267. UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  268. UIGraphicsEndImageContext();
  269. return newImage;
  270. }
  271. #pragma mark 二分法
  272. ///二分法,block回调中finallData长度不为零表示最终压缩到了指定的大小,如果为零则表示压缩不到指定大小。tempData表示当前能够压缩到的最小值。
  273. + (void)halfFuntion:(NSArray *)arr image:(UIImage *)image sourceData:(NSData *)finallImageData maxSize:(NSInteger)maxSize resultBlock:(void(^)(NSData *finallData, NSData *tempData))block {
  274. NSData *tempData = [NSData data];
  275. NSUInteger start = 0;
  276. NSUInteger end = arr.count - 1;
  277. NSUInteger index = 0;
  278. NSUInteger difference = NSIntegerMax;
  279. while(start <= end) {
  280. index = start + (end - start)/2;
  281. finallImageData = UIImageJPEGRepresentation(image,[arr[index] floatValue]);
  282. NSUInteger sizeOrigin = finallImageData.length;
  283. NSUInteger sizeOriginKB = sizeOrigin / 1000;
  284. NSLog(@"当前降到的质量:%ld", (unsigned long)sizeOriginKB);
  285. // NSLog(@"\nstart:%zd\nend:%zd\nindex:%zd\n压缩系数:%lf", start, end, (unsigned long)index, [arr[index] floatValue]);
  286. if (sizeOriginKB > maxSize) {
  287. start = index + 1;
  288. } else if (sizeOriginKB < maxSize) {
  289. if (maxSize-sizeOriginKB < difference) {
  290. difference = maxSize-sizeOriginKB;
  291. tempData = finallImageData;
  292. }
  293. if (index<=0) {
  294. break;
  295. }
  296. end = index - 1;
  297. } else {
  298. break;
  299. }
  300. }
  301. NSData *d = [NSData data];
  302. if (tempData.length==0) {
  303. d = finallImageData;
  304. }
  305. if (block) {
  306. block(tempData, d);
  307. }
  308. // return tempData;
  309. }
  310. + (UIImage *)fixOrientation:(UIImage *)image {
  311. // No-op if the orientation is already correct
  312. if (image.imageOrientation == UIImageOrientationUp) return image;
  313. // We need to calculate the proper transformation to make the image upright.
  314. // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
  315. CGAffineTransform transform = CGAffineTransformIdentity;
  316. switch (image.imageOrientation) {
  317. case UIImageOrientationDown:
  318. case UIImageOrientationDownMirrored:
  319. transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height);
  320. transform = CGAffineTransformRotate(transform, M_PI);
  321. break;
  322. case UIImageOrientationLeft:
  323. case UIImageOrientationLeftMirrored:
  324. transform = CGAffineTransformTranslate(transform, image.size.width, 0);
  325. transform = CGAffineTransformRotate(transform, M_PI_2);
  326. break;
  327. case UIImageOrientationRight:
  328. case UIImageOrientationRightMirrored:
  329. transform = CGAffineTransformTranslate(transform, 0, image.size.height);
  330. transform = CGAffineTransformRotate(transform, -M_PI_2);
  331. break;
  332. default:
  333. break;
  334. }
  335. switch (image.imageOrientation) {
  336. case UIImageOrientationUpMirrored:
  337. case UIImageOrientationDownMirrored:
  338. transform = CGAffineTransformTranslate(transform, image.size.width, 0);
  339. transform = CGAffineTransformScale(transform, -1, 1);
  340. break;
  341. case UIImageOrientationLeftMirrored:
  342. case UIImageOrientationRightMirrored:
  343. transform = CGAffineTransformTranslate(transform, image.size.height, 0);
  344. transform = CGAffineTransformScale(transform, -1, 1);
  345. break;
  346. default:
  347. break;
  348. }
  349. // Now we draw the underlying CGImage into a new context, applying the transform
  350. // calculated above.
  351. CGContextRef ctx = CGBitmapContextCreate(NULL, image.size.width, image.size.height,
  352. CGImageGetBitsPerComponent(image.CGImage), 0,
  353. CGImageGetColorSpace(image.CGImage),
  354. CGImageGetBitmapInfo(image.CGImage));
  355. CGContextConcatCTM(ctx, transform);
  356. switch (image.imageOrientation) {
  357. case UIImageOrientationLeft:
  358. case UIImageOrientationLeftMirrored:
  359. case UIImageOrientationRight:
  360. case UIImageOrientationRightMirrored:
  361. // Grr...
  362. CGContextDrawImage(ctx, CGRectMake(0, 0, image.size.height, image.size.width), image.CGImage);
  363. break;
  364. default:
  365. CGContextDrawImage(ctx, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
  366. break;
  367. }
  368. // And now we just create a new UIImage from the drawing context
  369. CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
  370. UIImage *img = [UIImage imageWithCGImage:cgimg];
  371. CGContextRelease(ctx);
  372. CGImageRelease(cgimg);
  373. return img;
  374. }
  375. - (UIImage*)imageWaterMarkWithImage:(UIImage *)image imageRect:(CGRect)imgRect alpha:(CGFloat)alpha
  376. {
  377. return [self imageWaterMarkWithString:nil rect:CGRectZero attribute:nil image:image imageRect:imgRect alpha:alpha];
  378. }
  379. - (UIImage*)imageWaterMarkWithImage:(UIImage*)image imagePoint:(CGPoint)imgPoint alpha:(CGFloat)alpha
  380. {
  381. return [self imageWaterMarkWithString:nil point:CGPointZero attribute:nil image:image imagePoint:imgPoint alpha:alpha];
  382. }
  383. - (UIImage*)imageWaterMarkWithString:(NSString*)str rect:(CGRect)strRect attribute:(NSDictionary *)attri
  384. {
  385. return [self imageWaterMarkWithString:str rect:strRect attribute:attri image:nil imageRect:CGRectZero alpha:0];
  386. }
  387. - (UIImage*)imageWaterMarkWithString:(NSString*)str point:(CGPoint)strPoint attribute:(NSDictionary*)attri
  388. {
  389. return [self imageWaterMarkWithString:str point:strPoint attribute:attri image:nil imagePoint:CGPointZero alpha:0];
  390. }
  391. - (UIImage*)imageWaterMarkWithString:(NSString*)str point:(CGPoint)strPoint attribute:(NSDictionary*)attri image:(UIImage*)image imagePoint:(CGPoint)imgPoint alpha:(CGFloat)alpha
  392. {
  393. UIGraphicsBeginImageContext(self.size);
  394. [self drawAtPoint:CGPointMake(0, 0) blendMode:kCGBlendModeNormal alpha:1.0];
  395. if (image) {
  396. [image drawAtPoint:imgPoint blendMode:kCGBlendModeNormal alpha:alpha];
  397. }
  398. if (str) {
  399. [str drawAtPoint:strPoint withAttributes:attri];
  400. }
  401. UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
  402. UIGraphicsEndImageContext();
  403. return resultImage;
  404. }
  405. - (UIImage*)imageWaterMarkWithString:(NSString*)str rect:(CGRect)strRect attribute:(NSDictionary *)attri image:(UIImage *)image imageRect:(CGRect)imgRect alpha:(CGFloat)alpha
  406. {
  407. UIGraphicsBeginImageContext(self.size);
  408. [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height) blendMode:kCGBlendModeNormal alpha:1.0];
  409. if (image) {
  410. [image drawInRect:imgRect blendMode:kCGBlendModeNormal alpha:alpha];
  411. }
  412. if (str) {
  413. [str drawInRect:strRect withAttributes:attri];
  414. }
  415. UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
  416. UIGraphicsEndImageContext();
  417. return resultImage;
  418. }
  419. - (UIImage *)imageAddCornerWithCornerRadiusArray:(NSArray<NSNumber *> *)cornerRadius lineWidth:(CGFloat)lineWidth borderPosition:(QMUIImageBorderPosition)borderPosition lineColor:(NSString *)lineColor andSize:(CGSize)size {
  420. CGRect rect = CGRectMake(0, 0, size.width, size.height);
  421. UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
  422. CGContextRef contextRef = UIGraphicsGetCurrentContext();
  423. UIBezierPath *path = [UIBezierPath qmui_bezierPathWithRoundedRect:rect cornerRadiusArray:cornerRadius lineWidth:lineWidth];
  424. if (borderPosition == QMUIImageBorderPositionAll) {
  425. CGContextSetStrokeColorWithColor(contextRef, RQColorFromHexString(lineColor).CGColor);
  426. [path setLineWidth:lineWidth];
  427. [path stroke];
  428. } else {
  429. // TODO 使用bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:这个系统接口
  430. if ((QMUIImageBorderPositionBottom & borderPosition) == QMUIImageBorderPositionBottom) {
  431. [path moveToPoint:CGPointMake(0, size.height - lineWidth / 2)];
  432. [path addLineToPoint:CGPointMake(size.width, size.height - lineWidth / 2)];
  433. }
  434. if ((QMUIImageBorderPositionTop & borderPosition) == QMUIImageBorderPositionTop) {
  435. [path moveToPoint:CGPointMake(0, lineWidth / 2)];
  436. [path addLineToPoint:CGPointMake(size.width, lineWidth / 2)];
  437. }
  438. if ((QMUIImageBorderPositionLeft & borderPosition) == QMUIImageBorderPositionLeft) {
  439. [path moveToPoint:CGPointMake(lineWidth / 2, 0)];
  440. [path addLineToPoint:CGPointMake(lineWidth / 2, size.height)];
  441. }
  442. if ((QMUIImageBorderPositionRight & borderPosition) == QMUIImageBorderPositionRight) {
  443. [path moveToPoint:CGPointMake(size.width - lineWidth / 2, 0)];
  444. [path addLineToPoint:CGPointMake(size.width - lineWidth / 2, size.height)];
  445. }
  446. [path setLineWidth:lineWidth];
  447. [path closePath];
  448. }
  449. CGContextAddPath(contextRef,path.CGPath);
  450. CGContextClip(contextRef);
  451. [self drawInRect:rect];
  452. CGContextDrawPath(contextRef, kCGPathFillStroke);
  453. UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  454. UIGraphicsEndImageContext();
  455. return image;
  456. }
  457. /**
  458. 获取网络图片高度
  459. */
  460. + (CGSize)getImageSizeWithURL:(id)URL
  461. {
  462. NSURL * url = nil;
  463. if ([URL isKindOfClass:[NSURL class]]) {
  464. url = URL;
  465. }
  466. if ([URL isKindOfClass:[NSString class]]) {
  467. url = [NSURL URLWithString:URL];
  468. }
  469. if (!URL) {
  470. return CGSizeZero;
  471. }
  472. CGImageSourceRef imageSourceRef = CGImageSourceCreateWithURL((CFURLRef)url, NULL);
  473. CGFloat width = 0, height = 0;
  474. if (imageSourceRef) {
  475. // 获取图像属性
  476. CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSourceRef, 0, NULL);
  477. //以下是对手机32位、64位的处理
  478. if (imageProperties != NULL) {
  479. CFNumberRef widthNumberRef = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelWidth);
  480. #if defined(__LP64__) && __LP64__
  481. if (widthNumberRef != NULL) {
  482. CFNumberGetValue(widthNumberRef, kCFNumberFloat64Type, &width);
  483. }
  484. CFNumberRef heightNumberRef = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelHeight);
  485. if (heightNumberRef != NULL) {
  486. CFNumberGetValue(heightNumberRef, kCFNumberFloat64Type, &height);
  487. }
  488. #else
  489. if (widthNumberRef != NULL) {
  490. CFNumberGetValue(widthNumberRef, kCFNumberFloat32Type, &width);
  491. }
  492. CFNumberRef heightNumberRef = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelHeight);
  493. if (heightNumberRef != NULL) {
  494. CFNumberGetValue(heightNumberRef, kCFNumberFloat32Type, &height);
  495. }
  496. #endif
  497. /***************** 此处解决返回图片宽高相反问题 *****************/
  498. // 图像旋转的方向属性
  499. NSInteger orientation = [(__bridge NSNumber *)CFDictionaryGetValue(imageProperties, kCGImagePropertyOrientation) integerValue];
  500. CGFloat temp = 0;
  501. switch (orientation) { // 如果图像的方向不是正的,则宽高互换
  502. case UIImageOrientationLeft: // 向左逆时针旋转90度
  503. case UIImageOrientationRight: // 向右顺时针旋转90度
  504. case UIImageOrientationLeftMirrored: // 在水平翻转之后向左逆时针旋转90度
  505. case UIImageOrientationRightMirrored: { // 在水平翻转之后向右顺时针旋转90度
  506. temp = width;
  507. width = height;
  508. height = temp;
  509. }
  510. break;
  511. default:
  512. break;
  513. }
  514. /***************** 此处解决返回图片宽高相反问题 *****************/
  515. CFRelease(imageProperties);
  516. }
  517. CFRelease(imageSourceRef);
  518. }
  519. return CGSizeMake(width, height);
  520. }
  521. + (UIImage*)videoImageWithvideoURL:(NSURL *)videoURL {
  522. NSString *cacheKeyStr = [[YYWebImageManager sharedManager] cacheKeyForURL:[NSURL URLWithString:videoURL.absoluteString]];
  523. UIImage *memoryImage = [[YYImageCache sharedCache] getImageForKey:cacheKeyStr];
  524. if (memoryImage) {
  525. return memoryImage;
  526. } else {
  527. UIImage *thumbnailImage = [self firstFrameWithVideoURL:videoURL size:CGSizeMake(RQ_SCREEN_WIDTH - 32.f, RQ_SCREEN_HEIGHT - (RQ_APPLICATION_NAV_BAR_HEIGHT + RQ_APPLICATION_STATUS_BAR_HEIGHT) - RQ_APPLICATION_SAFEAREA_BOTTOM_HEIGHT)];
  528. dispatch_async(dispatch_get_main_queue(), ^{
  529. YYImageCache * cache = [YYImageCache sharedCache];
  530. [cache setImage:thumbnailImage forKey:videoURL.absoluteString];
  531. });
  532. return thumbnailImage;
  533. }
  534. }
  535. // 获取视频第一帧
  536. + (UIImage*)firstFrameWithVideoURL:(NSURL*)url size:(CGSize)size {
  537. NSDictionary *opts = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
  538. AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:url options:opts];
  539. AVAssetImageGenerator *generator = [AVAssetImageGenerator assetImageGeneratorWithAsset:urlAsset];
  540. generator.appliesPreferredTrackTransform = YES;
  541. generator.maximumSize = CGSizeMake(size.width, size.height);
  542. NSError*error =nil;
  543. CGImageRef img = [generator copyCGImageAtTime:CMTimeMake(0, 10) actualTime:NULL error:&error];
  544. {
  545. return [UIImage imageWithCGImage:img];
  546. }
  547. return nil;
  548. }
  549. @end