You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

UIImageCVMatConverter.mm 14 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. //
  2. // UIImageCVMatConverter.m
  3. // lp
  4. //
  5. // Created by xiaojun on 2017/12/2.
  6. // Copyright © 2017年 xiaojun. All rights reserved.
  7. //
  8. #include "UIImageCVMatConverter.h"
  9. @implementation UIImageCVMatConverter
  10. +(UIImage *)UIImageFromCVMat:(cv::Mat)cvMat{
  11. NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];
  12. CGColorSpaceRef colorSpace;
  13. if (cvMat.elemSize() == 1) {
  14. colorSpace = CGColorSpaceCreateDeviceGray();
  15. } else {
  16. colorSpace = CGColorSpaceCreateDeviceRGB();
  17. }
  18. CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
  19. // Creating CGImage from cv::Mat
  20. CGImageRef imageRef = CGImageCreate(cvMat.cols, //width
  21. cvMat.rows, //height
  22. 8, //bits per component
  23. 8 * cvMat.elemSize(), //bits per pixel
  24. cvMat.step[0], //bytesPerRow
  25. colorSpace, //colorspace
  26. kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
  27. provider, //CGDataProviderRef
  28. NULL, //decode
  29. false, //should interpolate
  30. kCGRenderingIntentDefault //intent
  31. );
  32. // Getting UIImage from CGImage
  33. UIImage *finalImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationUp];
  34. CGImageRelease(imageRef);
  35. CGDataProviderRelease(provider);
  36. CGColorSpaceRelease(colorSpace);
  37. return finalImage;
  38. }
  39. //缩放调整图片
  40. + (UIImage *)scaleAndRotateImageBackCamera:(UIImage *)image
  41. {
  42. static int kMaxResolution = 480;
  43. CGImageRef imgRef = image.CGImage;
  44. CGFloat width = CGImageGetWidth(imgRef);
  45. CGFloat height = CGImageGetHeight(imgRef);
  46. CGAffineTransform transform = CGAffineTransformIdentity;
  47. CGRect bounds = CGRectMake(0, 0, width, height);
  48. if (width > kMaxResolution || height > kMaxResolution) {
  49. CGFloat ratio = width/height;
  50. if (ratio > 1) {
  51. bounds.size.width = kMaxResolution;
  52. bounds.size.height = bounds.size.width / ratio;
  53. } else {
  54. bounds.size.height = kMaxResolution;
  55. bounds.size.width = bounds.size.height * ratio;
  56. }
  57. }
  58. CGFloat scaleRatio = bounds.size.width / width;
  59. CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
  60. CGFloat boundHeight;
  61. UIImageOrientation orient = image.imageOrientation;
  62. switch(orient) {
  63. case UIImageOrientationUp:
  64. transform = CGAffineTransformIdentity;
  65. break;
  66. case UIImageOrientationUpMirrored:
  67. transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
  68. transform = CGAffineTransformScale(transform, -1.0, 1.0);
  69. break;
  70. case UIImageOrientationDown:
  71. transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
  72. transform = CGAffineTransformRotate(transform, M_PI);
  73. break;
  74. case UIImageOrientationDownMirrored:
  75. transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
  76. transform = CGAffineTransformScale(transform, 1.0, -1.0);
  77. break;
  78. case UIImageOrientationLeftMirrored:
  79. boundHeight = bounds.size.height;
  80. bounds.size.height = bounds.size.width;
  81. bounds.size.width = boundHeight;
  82. transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
  83. transform = CGAffineTransformScale(transform, -1.0, 1.0);
  84. transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
  85. break;
  86. case UIImageOrientationLeft:
  87. boundHeight = bounds.size.height;
  88. bounds.size.height = bounds.size.width;
  89. bounds.size.width = boundHeight;
  90. transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
  91. transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
  92. break;
  93. case UIImageOrientationRightMirrored:
  94. boundHeight = bounds.size.height;
  95. bounds.size.height = bounds.size.width;
  96. bounds.size.width = boundHeight;
  97. transform = CGAffineTransformMakeScale(-1.0, 1.0);
  98. transform = CGAffineTransformRotate(transform, M_PI / 2.0);
  99. break;
  100. case UIImageOrientationRight:
  101. boundHeight = bounds.size.height;
  102. bounds.size.height = bounds.size.width;
  103. bounds.size.width = boundHeight;
  104. transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
  105. transform = CGAffineTransformRotate(transform, M_PI / 2.0);
  106. break;
  107. default:
  108. [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
  109. }
  110. UIGraphicsBeginImageContext(bounds.size);
  111. CGContextRef context = UIGraphicsGetCurrentContext();
  112. if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
  113. CGContextScaleCTM(context, -scaleRatio, scaleRatio);
  114. CGContextTranslateCTM(context, -height, 0);
  115. } else {
  116. CGContextScaleCTM(context, scaleRatio, -scaleRatio);
  117. CGContextTranslateCTM(context, 0, -height);
  118. }
  119. CGContextConcatCTM(context, transform);
  120. CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
  121. UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext();
  122. UIGraphicsEndImageContext();
  123. NSLog(@"resize w%f,H%f",returnImage.size.width,returnImage.size.height);
  124. return returnImage;
  125. }
  126. +(UIImage*) imageWithMat:(const cv::Mat&) image andDeviceOrientation: (UIDeviceOrientation) orientation
  127. {
  128. UIImageOrientation imgOrientation = UIImageOrientationUp;
  129. switch (orientation)
  130. {
  131. case UIDeviceOrientationLandscapeLeft:
  132. imgOrientation =UIImageOrientationLeftMirrored; break;
  133. case UIDeviceOrientationLandscapeRight:
  134. imgOrientation = UIImageOrientationDown; break;
  135. case UIDeviceOrientationPortraitUpsideDown:
  136. imgOrientation = UIImageOrientationRightMirrored; break;
  137. case UIDeviceOrientationFaceUp:
  138. imgOrientation = UIImageOrientationRightMirrored; break;
  139. default:
  140. case UIDeviceOrientationPortrait:
  141. imgOrientation = UIImageOrientationRight; break;
  142. };
  143. return [UIImageCVMatConverter imageWithMat:image andImageOrientation:imgOrientation];
  144. }
  145. +(UIImage*) imageWithMat:(const cv::Mat&) image andImageOrientation: (UIImageOrientation) orientation;
  146. {
  147. cv::Mat rgbaView;
  148. if (image.channels() == 3)
  149. {
  150. cv::cvtColor(image, rgbaView, COLOR_BGR2BGRA);
  151. }
  152. else if (image.channels() == 4)
  153. {
  154. cv::cvtColor(image, rgbaView, COLOR_BGR2BGRA);
  155. }
  156. else if (image.channels() == 1)
  157. {
  158. cv::cvtColor(image, rgbaView, COLOR_GRAY2RGBA);
  159. }
  160. NSData *data = [NSData dataWithBytes:rgbaView.data length:rgbaView.elemSize() * rgbaView.total()];
  161. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  162. CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
  163. CGBitmapInfo bmInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
  164. // Creating CGImage from cv::Mat
  165. CGImageRef imageRef = CGImageCreate(rgbaView.cols, //width
  166. rgbaView.rows, //height
  167. 8, //bits per component
  168. 8 * rgbaView.elemSize(), //bits per pixel
  169. rgbaView.step.p[0], //bytesPerRow
  170. colorSpace, //colorspace
  171. bmInfo,// bitmap info
  172. provider, //CGDataProviderRef
  173. NULL, //decode
  174. false, //should interpolate
  175. kCGRenderingIntentDefault //intent
  176. );
  177. // Getting UIImage from CGImage
  178. UIImage *finalImage = [UIImage imageWithCGImage:imageRef scale:1 orientation:orientation];
  179. CGImageRelease(imageRef);
  180. CGDataProviderRelease(provider);
  181. CGColorSpaceRelease(colorSpace);
  182. return finalImage;
  183. }
  184. + (cv::Mat)cvMatFromUIImage:(UIImage *)image
  185. {
  186. CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
  187. CGFloat cols = image.size.width;
  188. CGFloat rows = image.size.height;
  189. cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels
  190. CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to data
  191. cols, // Width of bitmap
  192. rows, // Height of bitmap
  193. 8, // Bits per component
  194. cvMat.step[0], // Bytes per row
  195. colorSpace, // Colorspace
  196. kCGImageAlphaNoneSkipLast |
  197. kCGBitmapByteOrderDefault); // Bitmap info flags
  198. CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
  199. CGContextRelease(contextRef);
  200. CGColorSpaceRelease(colorSpace);
  201. cv::Mat cvMat3(rows, cols, CV_8UC3); // 8 bits per component, 4 channels
  202. cv::cvtColor(cvMat, cvMat3,COLOR_RGBA2RGB);
  203. return cvMat3;
  204. }
  205. + (UIImage *)scaleAndRotateImageFrontCamera:(UIImage *)image
  206. {
  207. static int kMaxResolution = 640;
  208. CGImageRef imgRef = image.CGImage;
  209. CGFloat width = CGImageGetWidth(imgRef);
  210. CGFloat height = CGImageGetHeight(imgRef);
  211. CGAffineTransform transform = CGAffineTransformIdentity;
  212. CGRect bounds = CGRectMake( 0, 0, width, height);
  213. if (width > kMaxResolution || height > kMaxResolution) {
  214. CGFloat ratio = width/height;
  215. if (ratio > 1) {
  216. bounds.size.width = kMaxResolution;
  217. bounds.size.height = bounds.size.width / ratio;
  218. } else {
  219. bounds.size.height = kMaxResolution;
  220. bounds.size.width = bounds.size.height * ratio;
  221. }
  222. }
  223. CGFloat scaleRatio = bounds.size.width / width;
  224. CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
  225. CGFloat boundHeight;
  226. UIImageOrientation orient = image.imageOrientation;
  227. switch(orient) {
  228. case UIImageOrientationUp:
  229. transform = CGAffineTransformIdentity;
  230. break;
  231. case UIImageOrientationUpMirrored:
  232. transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
  233. transform = CGAffineTransformScale(transform, -1.0, 1.0);
  234. break;
  235. case UIImageOrientationDown:
  236. transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
  237. transform = CGAffineTransformRotate(transform, M_PI);
  238. break;
  239. case UIImageOrientationDownMirrored:
  240. transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
  241. transform = CGAffineTransformScale(transform, 1.0, -1.0);
  242. break;
  243. case UIImageOrientationLeftMirrored:
  244. boundHeight = bounds.size.height;
  245. bounds.size.height = bounds.size.width;
  246. bounds.size.width = boundHeight;
  247. transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
  248. transform = CGAffineTransformScale(transform, -1.0, 1.0);
  249. transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
  250. break;
  251. case UIImageOrientationLeft:
  252. boundHeight = bounds.size.height;
  253. bounds.size.height = bounds.size.width;
  254. bounds.size.width = boundHeight;
  255. transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
  256. transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
  257. break;
  258. case UIImageOrientationRight:
  259. case UIImageOrientationRightMirrored:
  260. boundHeight = bounds.size.height;
  261. bounds.size.height = bounds.size.width;
  262. bounds.size.width = boundHeight;
  263. transform = CGAffineTransformMakeScale(-1.0, 1.0);
  264. transform = CGAffineTransformRotate(transform, M_PI / 2.0);
  265. break;
  266. default:
  267. [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
  268. }
  269. UIGraphicsBeginImageContext( bounds.size );
  270. CGContextRef context = UIGraphicsGetCurrentContext();
  271. if ( orient == UIImageOrientationRight || orient == UIImageOrientationLeft ) {
  272. CGContextScaleCTM(context, -scaleRatio, scaleRatio);
  273. CGContextTranslateCTM(context, -height, 0);
  274. }
  275. else {
  276. CGContextScaleCTM(context, scaleRatio, -scaleRatio);
  277. CGContextTranslateCTM(context, 0, -height);
  278. }
  279. CGContextConcatCTM( context, transform );
  280. CGContextDrawImage( UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef );
  281. UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext();
  282. UIGraphicsEndImageContext();
  283. return returnImage;
  284. }@end