#import "RScanPlugin.h" #import "FlutterRScanView.h" #import "RScanResult.h" #import "RScanCamera.h" #import "ZBarSDK.h" #import "ZXingObjC.h" @implementation RScanPlugin + (void)registerWithRegistrar:(NSObject*)registrar { FlutterMethodChannel* channel = [FlutterMethodChannel methodChannelWithName:@"com.rhyme_lph/r_scan" binaryMessenger:[registrar messenger]]; RScanPlugin* instance = [[RScanPlugin alloc] init]; [registrar addMethodCallDelegate:instance channel:channel]; FlutterRScanViewFactory * rScanView=[[FlutterRScanViewFactory alloc]initWithMessenger:registrar.messenger]; [registrar registerViewFactory:rScanView withId:@"com.rhyme_lph/r_scan_view"]; FlutterMethodChannel* cameraChannel = [FlutterMethodChannel methodChannelWithName:@"com.rhyme_lph/r_scan_camera/method" binaryMessenger:[registrar messenger]]; RScanCamera* camera = [[RScanCamera alloc]initWithRegistry:[registrar textures] messenger:[registrar messenger]]; [registrar addMethodCallDelegate:camera channel:cameraChannel]; } - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { if ([@"scanImagePath" isEqualToString:call.method]) { [self scanImagePath:call result:result]; }else if ([@"scanImageUrl" isEqualToString:call.method]) { [self scanImageUrl:call result:result]; }if ([@"scanImageMemory" isEqualToString:call.method]) { [self scanImageMemory:call result:result]; } else { result(FlutterMethodNotImplemented); } } - (void)scanImagePath:(FlutterMethodCall*)call result:(FlutterResult)result{ NSString * path=[call.arguments valueForKey:@"path"]; if([path isKindOfClass:[NSNull class]]){ result(@""); return; } //加载文件 NSFileHandle * fh=[NSFileHandle fileHandleForReadingAtPath:path]; NSData * data=[fh readDataToEndOfFile]; result([self getQrCode:data]); } -(NSDictionary *)zXingScan:(NSData *)data{ CGImageRef cgImage; // Fallback on earlier versions CGImageSourceRef sourceRef = CGImageSourceCreateWithData((CFDataRef)data, NULL); cgImage = CGImageSourceCreateImageAtIndex(sourceRef, 0, NULL); ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:cgImage]; ZXBinaryBitmap *bitmap = [ZXBinaryBitmap binaryBitmapWithBinarizer:[ZXHybridBinarizer binarizerWithSource:source]]; NSError *error = nil; ZXDecodeHints *hints = [ZXDecodeHints hints]; ZXMultiFormatReader *reader = [ZXMultiFormatReader reader]; ZXResult *result = [reader decode:bitmap hints:hints error:&error]; NSLog(@"zXing scan start"); if(result){ NSMutableDictionary *dict =[NSMutableDictionary dictionary]; NSString* contents = result.text; ZXBarcodeFormat format = result.barcodeFormat; [dict setValue:contents forKey:@"message"]; [dict setValue:[RScanResult getZXingType:format] forKey:@"type"]; NSArray* points = result.resultPoints; NSMutableArray * pointMap = [NSMutableArray array]; for(ZXResultPoint* poin in points){ [pointMap addObject:[self pointsToMap2:poin.x y:poin.y]]; } [dict setValue:pointMap forKey:@"points"]; return dict; } return nil; } -(NSDictionary *)zbarScan:(NSData *)data{ CGImageRef cgImage; // Fallback on earlier versions CGImageSourceRef sourceRef = CGImageSourceCreateWithData((CFDataRef)data, NULL); cgImage = CGImageSourceCreateImageAtIndex(sourceRef, 0, NULL); ZBarImage * zbarImage =[[ZBarImage alloc]initWithCGImage:cgImage]; ZBarImageScanner* scanner = [[ZBarImageScanner alloc]init]; [scanner setSymbology:ZBAR_NONE config:ZBAR_CFG_ENABLE to:1]; NSInteger resultInt = [scanner scanImage:zbarImage]; NSLog(@"zbar scan count:%ld",(long)resultInt); if (resultInt == 0) { return nil; }else{ ZBarSymbolSet* symbols = scanner.results; ZBarSymbol *symbol = nil; for(symbol in symbols){ break; } NSString* resultStr = symbol.data; NSLog(@"zbar scan result data:%@ , type:%@",resultStr,symbol.typeName); if (resultStr!=nil) { NSMutableDictionary *dict =[NSMutableDictionary dictionary]; [dict setValue:resultStr forKey:@"message"]; [dict setValue:[RScanResult getZBarType:symbol.type] forKey:@"type"]; NSMutableArray * points = [NSMutableArray array]; CGPoint topLeft=symbol.bounds.origin; CGPoint topRight=symbol.bounds.origin; topRight.x +=symbol.bounds.size.width; CGPoint bottomLeft=symbol.bounds.origin; bottomLeft.y +=symbol.bounds.size.height; CGPoint bottomRight=symbol.bounds.origin; bottomRight.x+=symbol.bounds.size.width; bottomRight.y+=symbol.bounds.size.height; [points addObject:[self pointsToMap:topLeft]]; [points addObject:[self pointsToMap:topRight]]; [points addObject:[self pointsToMap:bottomLeft]]; [points addObject:[self pointsToMap:bottomRight]]; [dict setValue:points forKey:@"points"]; return dict; } } return nil; } -(NSDictionary *)nativeScan:(NSData *)data{ CIImage * detectImage=[CIImage imageWithData:data]; CIDetector*detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}]; NSArray* feature = [detector featuresInImage:detectImage options: nil]; NSLog(@"native scan count:%lu",(unsigned long)feature.count); if(feature.count==0){ return nil; }else{ for(int index=0;index<[feature count];index ++){ CIQRCodeFeature * qrCode=[feature objectAtIndex:index]; NSString *resultStr=qrCode.messageString; if(resultStr!=nil){ NSMutableDictionary *dict =[NSMutableDictionary dictionary]; [dict setValue:resultStr forKey:@"message"]; [dict setValue:[RScanResult getType:AVMetadataObjectTypeQRCode] forKey:@"type"]; NSMutableArray * points = [NSMutableArray array]; CGPoint topLeft=qrCode.topLeft; CGPoint topRight=qrCode.topRight; CGPoint bottomLeft=qrCode.bottomLeft; CGPoint bottomRight=qrCode.bottomRight; [points addObject:[self pointsToMap:topLeft]]; [points addObject:[self pointsToMap:topRight]]; [points addObject:[self pointsToMap:bottomLeft]]; [points addObject:[self pointsToMap:bottomRight]]; [dict setValue:points forKey:@"points"]; return dict; } } } return nil; } -(NSDictionary *) getQrCode:(NSData *)data{ if (data) { NSDictionary * result = [self zbarScan:data]; if(result==nil){ result =[self zXingScan:data]; } if(result==nil){ result = [self nativeScan:data]; } return result; } return nil; } -(NSDictionary*) pointsToMap:(CGPoint) point{ NSMutableDictionary * dict = [NSMutableDictionary dictionary]; [dict setValue:@(point.x) forKey:@"X"]; [dict setValue:@(point.y) forKey:@"Y"]; return dict; } -(NSDictionary*) pointsToMap2:(float)x y:(float)y{ NSMutableDictionary * dict = [NSMutableDictionary dictionary]; [dict setValue:@(x) forKey:@"X"]; [dict setValue:@(y) forKey:@"Y"]; return dict; } - (void)scanImageUrl:(FlutterMethodCall*)call result:(FlutterResult)result{ NSString * url = [call.arguments valueForKey:@"url"]; NSURL* nsUrl=[NSURL URLWithString:url]; NSData * data=[NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:nsUrl] returningResponse:nil error:nil]; result([self getQrCode:data]); } - (void)scanImageMemory:(FlutterMethodCall*)call result:(FlutterResult)result{ FlutterStandardTypedData * uint8list=[call.arguments valueForKey:@"uint8list"]; result([self getQrCode:uint8list.data]); } @end