RScanPlugin.m 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #import "RScanPlugin.h"
  2. #import "FlutterRScanView.h"
  3. #import "RScanResult.h"
  4. #import "RScanCamera.h"
  5. #import "ZBarSDK.h"
  6. #import "ZXingObjC.h"
  7. @implementation RScanPlugin
  8. + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  9. FlutterMethodChannel* channel = [FlutterMethodChannel
  10. methodChannelWithName:@"com.rhyme_lph/r_scan"
  11. binaryMessenger:[registrar messenger]];
  12. RScanPlugin* instance = [[RScanPlugin alloc] init];
  13. [registrar addMethodCallDelegate:instance channel:channel];
  14. FlutterRScanViewFactory * rScanView=[[FlutterRScanViewFactory alloc]initWithMessenger:registrar.messenger];
  15. [registrar registerViewFactory:rScanView withId:@"com.rhyme_lph/r_scan_view"];
  16. FlutterMethodChannel* cameraChannel = [FlutterMethodChannel
  17. methodChannelWithName:@"com.rhyme_lph/r_scan_camera/method" binaryMessenger:[registrar messenger]];
  18. RScanCamera* camera = [[RScanCamera alloc]initWithRegistry:[registrar textures] messenger:[registrar messenger]];
  19. [registrar addMethodCallDelegate:camera channel:cameraChannel];
  20. }
  21. - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
  22. if ([@"scanImagePath" isEqualToString:call.method]) {
  23. [self scanImagePath:call result:result];
  24. }else if ([@"scanImageUrl" isEqualToString:call.method]) {
  25. [self scanImageUrl:call result:result];
  26. }if ([@"scanImageMemory" isEqualToString:call.method]) {
  27. [self scanImageMemory:call result:result];
  28. } else {
  29. result(FlutterMethodNotImplemented);
  30. }
  31. }
  32. - (void)scanImagePath:(FlutterMethodCall*)call result:(FlutterResult)result{
  33. NSString * path=[call.arguments valueForKey:@"path"];
  34. if([path isKindOfClass:[NSNull class]]){
  35. result(@"");
  36. return;
  37. }
  38. //加载文件
  39. NSFileHandle * fh=[NSFileHandle fileHandleForReadingAtPath:path];
  40. NSData * data=[fh readDataToEndOfFile];
  41. result([self getQrCode:data]);
  42. }
  43. -(NSDictionary *)zXingScan:(NSData *)data{
  44. CGImageRef cgImage;
  45. // Fallback on earlier versions
  46. CGImageSourceRef sourceRef = CGImageSourceCreateWithData((CFDataRef)data, NULL);
  47. cgImage = CGImageSourceCreateImageAtIndex(sourceRef, 0, NULL);
  48. ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:cgImage];
  49. ZXBinaryBitmap *bitmap = [ZXBinaryBitmap binaryBitmapWithBinarizer:[ZXHybridBinarizer binarizerWithSource:source]];
  50. NSError *error = nil;
  51. ZXDecodeHints *hints = [ZXDecodeHints hints];
  52. ZXMultiFormatReader *reader = [ZXMultiFormatReader reader];
  53. ZXResult *result = [reader decode:bitmap hints:hints error:&error];
  54. NSLog(@"zXing scan start");
  55. if(result){
  56. NSMutableDictionary *dict =[NSMutableDictionary dictionary];
  57. NSString* contents = result.text;
  58. ZXBarcodeFormat format = result.barcodeFormat;
  59. [dict setValue:contents forKey:@"message"];
  60. [dict setValue:[RScanResult getZXingType:format] forKey:@"type"];
  61. NSArray* points = result.resultPoints;
  62. NSMutableArray<NSDictionary *> * pointMap = [NSMutableArray array];
  63. for(ZXResultPoint* poin in points){
  64. [pointMap addObject:[self pointsToMap2:poin.x y:poin.y]];
  65. }
  66. [dict setValue:pointMap forKey:@"points"];
  67. return dict;
  68. }
  69. return nil;
  70. }
  71. -(NSDictionary *)zbarScan:(NSData *)data{
  72. CGImageRef cgImage;
  73. // Fallback on earlier versions
  74. CGImageSourceRef sourceRef = CGImageSourceCreateWithData((CFDataRef)data, NULL);
  75. cgImage = CGImageSourceCreateImageAtIndex(sourceRef, 0, NULL);
  76. ZBarImage * zbarImage =[[ZBarImage alloc]initWithCGImage:cgImage];
  77. ZBarImageScanner* scanner = [[ZBarImageScanner alloc]init];
  78. [scanner setSymbology:ZBAR_NONE config:ZBAR_CFG_ENABLE to:1];
  79. NSInteger resultInt = [scanner scanImage:zbarImage];
  80. NSLog(@"zbar scan count:%ld",(long)resultInt);
  81. if (resultInt == 0) {
  82. return nil;
  83. }else{
  84. ZBarSymbolSet* symbols = scanner.results;
  85. ZBarSymbol *symbol = nil;
  86. for(symbol in symbols){
  87. break;
  88. }
  89. NSString* resultStr = symbol.data;
  90. NSLog(@"zbar scan result data:%@ , type:%@",resultStr,symbol.typeName);
  91. if (resultStr!=nil) {
  92. NSMutableDictionary *dict =[NSMutableDictionary dictionary];
  93. [dict setValue:resultStr forKey:@"message"];
  94. [dict setValue:[RScanResult getZBarType:symbol.type] forKey:@"type"];
  95. NSMutableArray<NSDictionary *> * points = [NSMutableArray array];
  96. CGPoint topLeft=symbol.bounds.origin;
  97. CGPoint topRight=symbol.bounds.origin;
  98. topRight.x +=symbol.bounds.size.width;
  99. CGPoint bottomLeft=symbol.bounds.origin;
  100. bottomLeft.y +=symbol.bounds.size.height;
  101. CGPoint bottomRight=symbol.bounds.origin;
  102. bottomRight.x+=symbol.bounds.size.width;
  103. bottomRight.y+=symbol.bounds.size.height;
  104. [points addObject:[self pointsToMap:topLeft]];
  105. [points addObject:[self pointsToMap:topRight]];
  106. [points addObject:[self pointsToMap:bottomLeft]];
  107. [points addObject:[self pointsToMap:bottomRight]];
  108. [dict setValue:points forKey:@"points"];
  109. return dict;
  110. }
  111. }
  112. return nil;
  113. }
  114. -(NSDictionary *)nativeScan:(NSData *)data{
  115. CIImage * detectImage=[CIImage imageWithData:data];
  116. CIDetector*detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
  117. NSArray* feature = [detector featuresInImage:detectImage options: nil];
  118. NSLog(@"native scan count:%lu",(unsigned long)feature.count);
  119. if(feature.count==0){
  120. return nil;
  121. }else{
  122. for(int index=0;index<[feature count];index ++){
  123. CIQRCodeFeature * qrCode=[feature objectAtIndex:index];
  124. NSString *resultStr=qrCode.messageString;
  125. if(resultStr!=nil){
  126. NSMutableDictionary *dict =[NSMutableDictionary dictionary];
  127. [dict setValue:resultStr forKey:@"message"];
  128. [dict setValue:[RScanResult getType:AVMetadataObjectTypeQRCode] forKey:@"type"];
  129. NSMutableArray<NSDictionary *> * points = [NSMutableArray array];
  130. CGPoint topLeft=qrCode.topLeft;
  131. CGPoint topRight=qrCode.topRight;
  132. CGPoint bottomLeft=qrCode.bottomLeft;
  133. CGPoint bottomRight=qrCode.bottomRight;
  134. [points addObject:[self pointsToMap:topLeft]];
  135. [points addObject:[self pointsToMap:topRight]];
  136. [points addObject:[self pointsToMap:bottomLeft]];
  137. [points addObject:[self pointsToMap:bottomRight]];
  138. [dict setValue:points forKey:@"points"];
  139. return dict;
  140. }
  141. }
  142. }
  143. return nil;
  144. }
  145. -(NSDictionary *) getQrCode:(NSData *)data{
  146. if (data) {
  147. NSDictionary * result = [self zbarScan:data];
  148. if(result==nil){
  149. result =[self zXingScan:data];
  150. }
  151. if(result==nil){
  152. result = [self nativeScan:data];
  153. }
  154. return result;
  155. }
  156. return nil;
  157. }
  158. -(NSDictionary*) pointsToMap:(CGPoint) point{
  159. NSMutableDictionary * dict = [NSMutableDictionary dictionary];
  160. [dict setValue:@(point.x) forKey:@"X"];
  161. [dict setValue:@(point.y) forKey:@"Y"];
  162. return dict;
  163. }
  164. -(NSDictionary*) pointsToMap2:(float)x y:(float)y{
  165. NSMutableDictionary * dict = [NSMutableDictionary dictionary];
  166. [dict setValue:@(x) forKey:@"X"];
  167. [dict setValue:@(y) forKey:@"Y"];
  168. return dict;
  169. }
  170. - (void)scanImageUrl:(FlutterMethodCall*)call result:(FlutterResult)result{
  171. NSString * url = [call.arguments valueForKey:@"url"];
  172. NSURL* nsUrl=[NSURL URLWithString:url];
  173. NSData * data=[NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:nsUrl] returningResponse:nil error:nil];
  174. result([self getQrCode:data]);
  175. }
  176. - (void)scanImageMemory:(FlutterMethodCall*)call result:(FlutterResult)result{
  177. FlutterStandardTypedData * uint8list=[call.arguments valueForKey:@"uint8list"];
  178. result([self getQrCode:uint8list.data]);
  179. }
  180. @end