汉信码在iOS客户端中的应用和遇到的坑-创新互联
先简单介绍一下的 汉信码,基本上和 QRCode 即二维码 大差不差,可但是,二维码 一般扫描出来是 非中文的字符串(一般为链接),这就是汉信码区别于二维码的地方,汉信码是涵盖中文的,而且是国家自主研发非骗经费项目,虽然没有推广起来但是还是很好用的。其官网为:http://cscode.gs1cn.org/
成都创新互联主要从事成都网站设计、网站建设、网页设计、企业做网站、公司建网站等业务。立足成都服务武陟,10余年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:028-86922220简约而不简单的网站,大家可以看一下,在此提供一个样例:
其优点:汉字编码能力超强、极强抗污损、抗畸变识读能力、识读速度快、信息密度高、纠错能力强、图形美观等官方这么说的。
然后,针对不同的平台 官方提供了不同的解决方案来方便集成,但是 所提供的继承文档内容 少之又少:如下图为 iOS客户端即成 文档 非常简洁:
接下来 开始结合文档 开始集成 汉信数码 识别
鉴于 文档如此简洁 ok 知道了 函数需要传入一个图片的 usinged char 类型数据
于是乎 第一步 转化 灰度图片
-(UIImage*)getGrayImage:(UIImage*)sourceImage { int width = sourceImage.size.width; int height = sourceImage.size.height; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); CGContextRef context = CGBitmapContextCreate (nil, width, height, 8, // bits per component 0, colorSpace, kCGImageAlphaNone); CGColorSpaceRelease(colorSpace); if (context == NULL) { return nil; } CGContextDrawImage(context, CGRectMake(0, 0, width, height), sourceImage.CGImage); UIImage *grayImage = [UIImage p_w_picpathWithCGImage:CGBitmapContextCreateImage(context)]; CGContextRelease(context); return grayImage; }
第二步 拿到灰度图片 转为 一维数组数据
+ (unsigned char *) convertUIImageToBitmapRGBA8:(UIImage *) p_w_picpath { CGImageRef p_w_picpathRef = p_w_picpath.CGImage; // Create a bitmap context to draw the uip_w_picpath into CGContextRef context = [self newBitmapRGBA8ContextFromImage:p_w_picpathRef]; if(!context) { return NULL; } size_t width = CGImageGetWidth(p_w_picpathRef); size_t height = CGImageGetHeight(p_w_picpathRef); CGRect rect = CGRectMake(0, 0, width, height); // Draw p_w_picpath into the context to get the raw p_w_picpath data CGContextDrawImage(context, rect, p_w_picpathRef); // Get a pointer to the data unsigned char *bitmapData = (unsigned char *)CGBitmapContextGetData(context); // Copy the data and release the memory (return memory allocated with new) size_t bytesPerRow = CGBitmapContextGetBytesPerRow(context); size_t bufferLength = bytesPerRow * height; unsigned char *newBitmap = NULL; if(bitmapData) { newBitmap = (unsigned char *)malloc(sizeof(unsigned char) * bytesPerRow * height); if(newBitmap) { // Copy the data for(int i = 0; i < bufferLength; ++i) { newBitmap[i] = bitmapData[i]; } } free(bitmapData); } else { NSLog(@"Error getting bitmap pixel data\n"); } CGContextRelease(context); return newBitmap; }
在这里需要注意的是 对选择的图片 要做选景框处理 也就是需要截取只需要解码的部分图片 并进行一定的体积压缩 否则会出现溢出。
当时准备完毕之后 运行 ,扫描 汉信码 一直报 9001 错误 具体什么错误 官方文档并没有给出明确的解释,问题悬而未决。。。。
折磨了数周之后 仍然 未解决 ,细细想了一下 是否是 因为 汉信码 所提供 sdk 不支持 iOS CoreGraphics 框架的 数据输出 识别。
于是抱着试试的态度,把目标转向了 opencv 这个 跨平台的 图片处理库;
OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
使用 opencv 集成
第一步 转化 灰度图片
CGColorSpaceRef colorSpace = CGImageGetColorSpace(p_w_picpath.CGImage); CGFloat cols = p_w_picpath.size.width; CGFloat rows = p_w_picpath.size.height; cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to data cols, // Width of bitmap rows, // Height of bitmap 8, // Bits per component cvMat.step[0], // Bytes per row colorSpace, // Colorspace kCGImageAlphaNoneSkipLast | kCGBitmapByteOrderDefault); // Bitmap info flags CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), p_w_picpath.CGImage); CGContextRelease(contextRef); CGColorSpaceRelease(colorSpace); cv::Mat matGrey; //cvtColor函数对matImage进行灰度处理 cv::cvtColor(cvMat, matGrey, CV_BGR2GRAY);// 转换成灰色 //使用灰度后的IplImage形式图像,用OSTU算法算阈值:threshold IplImage grey = matGrey;
第二步从 灰度图片中 获取到 一维数组
unsigned char* dataImage = (unsigned char*)grey.p_w_picpathData;
第三步 调用 汉信码 sdk
Byte vecNetMap[189*189]; try { int versionSize = preprocessImg(dataImage, srcp_w_picpath.size.width, srcp_w_picpath.size.height, vecNetMap); if (versionSize >= 23 && versionSize < 189) { Byte szInfo [7828]; int ret = DeCodeCsbyte(vecNetMap, versionSize, szInfo); if (ret > 0) { NSStringEncoding gbkEncoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000); NSString *str = [[NSString alloc] initWithBytes:szInfo length:ret encoding:gbkEncoding]; NSLog(@"解码汉信-------%@",str); if (_blockHanxinResult) { _blockHanxinResult(str); } 一定要 注意 !!! 返回UI线程 停止扫描 否则会应用会奔溃 dispatch_async(dispatch_get_main_queue(), ^{ [self stopScan]; }); } }else{ self.srcp_w_picpath = nil; self.hximg = nil; } } catch (int i) { }
iOS 集成 汉信码 功能算是 告一段落。。。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
网站题目:汉信码在iOS客户端中的应用和遇到的坑-创新互联
网站网址:http://scjbc.cn/article/poegp.html