引言
从CSDN下载Demo源码:https://download.csdn.net/download/u011018979/19268420
- 功能:扫描银行卡识别信息( 银行名称、 银行卡号)并截取银行卡图像
- 应用场景:快速填充银行卡号的场景,比如商户进件、实名认证
- 原理:
3.1、自定义相机并利用第三方库SDKlibexbankcardios.a
、libbexbankcard.a
进行识别(识别次数无限,免费
)3.2、添加自定义的扫描界面(中间有一个镂空窗口和来回移动的扫描线)
- 原理文章:https://kunnan.blog.csdn.net/article/details/117421214
- 如果无法下载Demo,请关注公众号:【iOS逆向】,进行获取
支持身份证号码识别
I 扫描银行卡
1.1 引入第三方SDK和头文件
exbankcard.h
BankCard.h
exbankcardcore.h
libexbankcardios.a
libbexbankcard.a
https://github.com/zhangkn/AVCapture4bank
other linker flags -force_load libbexbankcard.a
other linker flags -force_load libexbankcardios.a
1.2 获取信息(解码)
#pragma mark--扫描银行卡--
- (void)parseBankImageBuffer:(CVImageBufferRef)imageBuffer {
#if TARGET_IPHONE_SIMULATOR
#else
size_t width_t= CVPixelBufferGetWidth(imageBuffer);
size_t height_t = CVPixelBufferGetHeight(imageBuffer);
CVPlanarPixelBufferInfo_YCbCrBiPlanar *planar = CVPixelBufferGetBaseAddress(imageBuffer);
size_t offset = NSSwapBigIntToHost(planar->componentInfoY.offset);
unsigned char* baseAddress = (unsigned char *)CVPixelBufferGetBaseAddress(imageBuffer);
unsigned char* pixelAddress = baseAddress + offset;
size_t cbCrOffset = NSSwapBigIntToHost(planar->componentInfoCbCr.offset);
uint8_t *cbCrBuffer = baseAddress + cbCrOffset;
CGSize size = CGSizeMake(width_t, height_t);
CGRect effectRect = [IDCardRectManager getEffectImageRect:size];
CGRect rect = [IDCardRectManager getGuideFrame:effectRect];
int width = ceilf(width_t);
int height = ceilf(height_t);
unsigned char result [512];
int resultLen = BankCardNV12(result, 512, pixelAddress, cbCrBuffer, width, height, rect.origin.x, rect.origin.y, rect.origin.x+rect.size.width, rect.origin.y+rect.size.height);
if(resultLen > 0) {
int charCount = [IDCardRectManager docode:result len:resultLen];
if(charCount > 0) {
// CGRect subRect = [IDCardRectManager getCorpCardRect:width height:height guideRect:rect charCount:charCount];
self.isHasResult = YES;
if ([self.captureSession isRunning]) {
[self.captureSession stopRunning];
}
UIImage *image = [UIImage getImageStream:imageBuffer];
// __block UIImage *subImg = [UIImage getSubImage:subRect inImage:image];
char *numbers = [IDCardRectManager getNumbers];
NSString *numberStr = [NSString stringWithCString:numbers encoding:NSASCIIStringEncoding];
NSString *bank = [BankCardSearch getBankNameByBin:numbers count:charCount];
NSLog(@"\n卡号%@\n银行类型%@",numberStr,bank);
BankCardInfo *model = [JYBDBankCardInfo new];
model.bankNumber = numberStr;
model.bankName = bank;
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
dispatch_async(dispatch_get_main_queue(), ^{
if (self.finish)
{
self.finish(model, image);
}
});
}
}
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
self.isInProcessing = NO;
#endif
}
1.3 图片裁剪
- (void)parseBankImageBuffer:(CVImageBufferRef)imageBuffer {
size_t width_t= CVPixelBufferGetWidth(imageBuffer);
size_t height_t = CVPixelBufferGetHeight(imageBuffer);
CGSize size = CGSizeMake(width_t, height_t);
CGRect effectRect = [IDCardRectManager getEffectImageRect:size];
CGRect rect = [IDCardRectManager getGuideFrame:effectRect];
UIImage *image = [UIImage getImageStream:imageBuffer];// image 原图
__block UIImage *subImg = [UIImage getSubImage:rect inImage:image];// 裁剪 rect
}
- 工具方法
+ (UIImage *)getImageStream:(CVImageBufferRef)imageBuffer {
CIImage *ciImage = [CIImage imageWithCVPixelBuffer:imageBuffer];
CIContext *temporaryContext = [CIContext contextWithOptions:nil];
CGImageRef videoImage = [temporaryContext createCGImage:ciImage fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(imageBuffer), CVPixelBufferGetHeight(imageBuffer))];
UIImage *image = [[UIImage alloc] initWithCGImage:videoImage];
CGImageRelease(videoImage);
return image;
}
+ (UIImage *)getSubImage:(CGRect)rect inImage:(UIImage*)image {
CGImageRef subImageRef = CGImageCreateWithImageInRect(image.CGImage, rect);
CGRect smallBounds = CGRectMake(0, 0, CGImageGetWidth(subImageRef), CGImageGetHeight(subImageRef));
UIGraphicsBeginImageContext(smallBounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, smallBounds, subImageRef);
UIImage* smallImage = [UIImage imageWithCGImage:subImageRef];
CFRelease(subImageRef);
UIGraphicsEndImageContext();
return smallImage;
}
1.4 根据numbers和charCount查询银行名称
https://kunnan.blog.csdn.net/article/details/120390267
II 常见问题
2.1 iOS13适配:present 半屏问题
全屏显示采集界面
https://blog.csdn.net/z929118967/article/details/104477314
- (NSMutableArray *)FullScreenClasss{
if(_FullScreenClasss == nil){
[_FullScreenClasss addObject:@"KNAVCapture4IDfrontViewController"];
}
return _FullScreenClasss;
}
2.2 Undefined symbols for architecture arm64
Undefined symbols for architecture arm64:
"_ZIM_SaveImage", referenced from:
ImgSave(tagIMG, char const*) in libbexbankcard.a(gjimage.o)
"_ZIM_LoadImage", referenced from:
ImgLoad(tagIMG&, char const*) in libbexbankcard.a(gjimage.o)
"_ZIM_DoneImage", referenced from:
ImgLoad(tagIMG&, char const*) in libbexbankcard.a(gjimage.o)
ld: symbol(s) not found for architecture arm64
解决办法:在TARGETS和PROJECT 两处中build settings 搜索 ENABLE_TESTABILITY 改为NO
RN项目,Dead Code Stripping 设置为yes
see also
公号:iOS逆向