iOS小技能: OCR 之银行卡/身份证信息识别(免费次数无限)

本文涉及的产品
通用文字识别,通用文字识别 200次/月
小语种识别,小语种识别 200次/月
票据凭证识别,票据凭证识别 200次/月
简介: 1. 功能:扫描银行卡识别信息( 银行名称、 银行卡号)并截取银行卡图像2. 应用场景:快速填充银行卡号的场景,比如商户进件、实名认证

引言

从CSDN下载Demo源码:https://download.csdn.net/download/u011018979/19268420

  1. 功能:扫描银行卡识别信息( 银行名称、 银行卡号)并截取银行卡图像
  2. 应用场景:快速填充银行卡号的场景,比如商户进件、实名认证
  3. 原理:
3.1、自定义相机并利用第三方库SDK libexbankcardios.alibbexbankcard.a进行识别(识别 次数无限,免费 )

3.2、添加自定义的扫描界面(中间有一个镂空窗口和来回移动的扫描线)

  1. 原理文章:https://kunnan.blog.csdn.net/article/details/117421214
  2. 如果无法下载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逆向

目录
相关文章
|
2月前
|
JSON 文字识别 小程序
微信小程序OCR插件,实现身份证、行驶证、银行卡、营业执照和驾驶证等识别
微信小程序OCR插件,实现身份证、行驶证、银行卡、营业执照和驾驶证等识别
324 0
|
5月前
|
文字识别
印刷文字识别使用问题之是否支持非标发票的识别
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
5月前
|
存储 文字识别 运维
印刷文字识别使用问题之如何开通统一识别
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
5月前
|
文字识别 容器
印刷文字识别使用问题之是否支持医疗检测报告识别
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
5月前
|
文字识别 API 开发工具
印刷文字识别使用问题之如何进行批量识别
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
5月前
|
人工智能 文字识别 开发工具
印刷文字识别使用问题之是否支持识别并返回文字在图片中的位置信息
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
5月前
|
人工智能 JSON 文字识别
印刷文字识别使用问题之如何数电发票进行识别
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
5月前
|
文字识别 数据安全/隐私保护 iOS开发
印刷文字识别使用问题之如何识别礼品册上的卡号、密码信息
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
5月前
|
机器学习/深度学习 文字识别 API
印刷文字识别使用问题之是否支持识别香港和澳门食品经营许可证
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
5月前
|
文字识别 开发工具
印刷文字识别使用问题之是否支持识别手写体
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
印刷文字识别使用问题之是否支持识别手写体