先简单介绍一下的 汉信码,基本上和 QRCode 即二维码 大差不差,可但是,二维码 一般扫描出来是 非中文的字符串(一般为链接),这就是汉信码区别于二维码的地方,汉信码是涵盖中文的,而且是国家自主研发非骗经费项目,虽然没有推广起来但是还是很好用的。其官网为:http://cscode.gs1cn.org/
简约而不简单的网站,大家可以看一下,在此提供一个样例:
其优点:汉字编码能力超强、极强抗污损、抗畸变识读能力、识读速度快、信息密度高、纠错能力强、图形美观等官方这么说的。
然后,针对不同的平台 官方提供了不同的解决方案来方便集成,但是 所提供的继承文档内容 少之又少:如下图为 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 集成 汉信码 功能算是 告一段落。。。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。