百度OCR-图片文本识别

封装API方式请求
做的时候遇到:oc提供的base64二进制方法,base64之后有\r,\n这两个字符,需要移除,移除之后urlEncode

1.请求token

- (void)authWithAPIKey:(NSString *)strApi secretKey:(NSString *)strSecret {
if ([self checkLocalTokenValidWithApiKey:strApi secretKey:strSecret])

{

//本地token有效,并且已经复制self.strToken,重发之前因为token失败的任务

[self handleGetStokenSuccess];

return;

}

NSString *strUrl = @"https://aip.baidubce.com/oauth/2.0/token";

NSDictionary *dicParam = @{@"grant_type":@"client_credentials",

@"client_id":strApi,

@"client_secret":strSecret};

[self requestWithParams:dicParam url:strUrl completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

if (error)

{

NSLog(@"request token error:\n%@",error);

}

else

{

if (data)

{

NSDictionary *dicRe = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];

NSString *token = [dicRe objectForKey:@"access_token"];

//本地token更新

if (token)

{

self.strToken = token;

//这里定义了几个常量用于存储本地token相关信息

NSDictionary *dicToken = @{USERDEFAULT_OCR_TOKEN:token,USERDEFAULT_OCR_TIME:[NSString stringWithFormat:@"%f",[NSDate date].timeIntervalSince1970],USERDEFAULT_OCR_API:strApi,USERDEFAULT_OCR_SECRET:strSecret};

[[NSUserDefaults standardUserDefaults] setObject:dicToken forKey:USERDEFAULT_OCR];

[self handleGetStokenSuccess];

}

else

{

NSString *error = dicRe[@"error"];

NSLog(@"request token error:\n%@",error);

}

}

}

}];

}

2.发起请求

/**

图像二进制识别文字

@param imageData 1

@param successHandler 1

@param failHandler 1

*/

- (void)detectTextFromImageData:(NSData *)imageData

successHandler: (void (^)(id result))successHandler

failHandler: (void (^)(NSError* err))failHandler

{

if (!self.strToken.length)

{

//未获取百度token

_bOcrWaiting = YES;

//添加等待任务

[self addWaiting:imageData successHandler:successHandler failHandler:failHandler];

[self authWithAPIKey:BD_OCR_API_KEY secretKey:BD_OCR_SECRET_KEY];

return;

}

if (imageData == nil)

{

//data为空

NSLog(@"ocr  data is nil");

[self handleFaileHandle:failHandler errorCode:-1 errMessage:@"ocr  data is nil"];

return;

}

//将data base64

NSString *strBase64 = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

//删除base64中的换行符

strBase64 = [strBase64 stringByReplacingOccurrencesOfString:@"\n" withString:@""];

strBase64 = [strBase64 stringByReplacingOccurrencesOfString:@"\r" withString:@""];

//配置参数

NSMutableDictionary *params = [[NSMutableDictionary alloc] init];

//是否返回识别结果中每一行的置信度

[params setObject:@"false" forKey:@"probability"];

//是否检测语言,默认不检测。

[params setObject:@"1" forKey:@"detect_language"];

//是否检测图像朝向,默认不检测,false/true

[params setObject:@"false" forKey:@"detect_direction"];

//鉴权token

[params setObject:self.strToken forKey:@"token"];

//识别语言类型,默认为CHN_ENG.CHN_ENG:中英文混合; ENG:英文;POR:葡萄牙语; FRE:法语;GER:德语; ITA:意大利语;SPA:西班牙语;RUS:俄语;JAP:日语;KOR:韩语

[params setObject:@"CHN_ENG" forKey:@"language_type"];

//image数据,二进制文件进行base64编码后,最短边至少15px,最长边最大4096px,base64编码后大小不超过4M

[params setObject:strBase64 forKey:@"image"];

[params setObject:self.strToken forKey:@"access_token"];

NSString *strUrl = @"https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic";

[self requestWithParams:params

url:strUrl

completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error)

{

if (error)

{

//网络请求出错

NSLog(@"ocr error:\n%@",error);

[self handleFaileHandle:failHandler errorCode:-1 errMessage:error.description];

}

else

{

if (data)

{

NSString *strD = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

NSLog(@"ocr strResult:\n%@",strD);

NSDictionary *dicResult = [NSJSONSerialization JSONObjectWithData:[strD dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableLeaves error:nil];

[strD release];

if (dicResult[@"words_result"])

{

//识别成功

if (successHandler != nil)

{

successHandler(dicResult);

}

}

else

{

//识别出错

NSInteger err_code = [dicResult[@"error_code"] integerValue];

if (err_code == 100 ||//无效的access_token参数

err_code == 110 ||//access_token无效

err_code == 111)//access token过期

{

_bOcrWaiting = YES;

//移出无效的token

self.strToken = @"";

[[NSUserDefaults standardUserDefaults] removeObjectForKey:USERDEFAULT_OCR];

//添加任务到等待列表

[self addWaiting:imageData successHandler:successHandler failHandler:failHandler];

//重新获取token

[self authWithAPIKey:BD_OCR_API_KEY secretKey:BD_OCR_SECRET_KEY];

}

else if (err_code == 216201 ||

err_code == 216202)

{

[self handleFaileHandle:failHandler errorCode:err_code errMessage:@"不支持的图片"];

}

else

{

NSString *err_msg = dicResult[@"error_msg"];

[self handleFaileHandle:failHandler errorCode:err_code errMessage:err_msg];

}

}

NSLog(@"ocr dicResult:\n%@",dicResult);

}

else

{

//一个报错处理

[self handleFaileHandle:failHandler errorCode:-1 errMessage:@"ocr has no result data"];

NSLog(@"ocr has no result data");

}

}

}];

[params release];

}

3.自己写的请求方法

/**

post网络请求

@param params 参数

@param strUrl url

@param completionHandler 1

*/

- (void)requestWithParams:(NSDictionary *)params url:(NSString *)strUrl completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler{

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:strUrl]];

request.HTTPMethod = @"POST";

request.HTTPBody = [[self transformDictionaryToString:params] dataUsingEncoding:NSUTF8StringEncoding];

NSURLSessionDataTask *dataTask = [self.pUrlSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error)

{

if (completionHandler) completionHandler(data,response,error);

}];

[dataTask resume];

}

4.网络请求相关的两个工具方法

/**

字典转字符串

@param dict 1

@return 1

*/

- (NSString *)transformDictionaryToString:(NSDictionary *)dict {

NSMutableString *strParams = [NSMutableString string];

//遍历并拼接

for (NSString *key in dict.allKeys)

{

[strParams appendFormat:@"%@=%@&",[self urlEncodeString:key],[self urlEncodeString:[dict objectForKey:key]]];

}

NSString *str = [strParams substringToIndex:strParams.length - 1];

return str;

}
/**

urlEncode,来源AFNetworking -> AFURLRequestSerialization.m NSString * AFPercentEscapedStringFromString(NSString *string){}

@param string 1

@return 1

*/

- (NSString *)urlEncodeString:(NSString *)string {

static NSString * const kAFCharactersGeneralDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4

static NSString * const kAFCharactersSubDelimitersToEncode = @"!$&'()*+,;=";

NSMutableCharacterSet * allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];

[allowedCharacterSet removeCharactersInString:[kAFCharactersGeneralDelimitersToEncode stringByAppendingString:kAFCharactersSubDelimitersToEncode]];

// FIXME: https://github.com/AFNetworking/AFNetworking/pull/3028

// return [string stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];

static NSUInteger const batchSize = 50;

NSUInteger index = 0;

NSMutableString *escaped = [@"".mutableCopy autorelease];

while (index < string.length) {

@autoreleasepool {

NSUInteger length = MIN(string.length - index, batchSize);

NSRange range = NSMakeRange(index, length);

// To avoid breaking up character sequences such as 

range = [string rangeOfComposedCharacterSequencesForRange:range];

NSString *substring = [string substringWithRange:range];

NSString *encoded = [substring stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];

[escaped appendString:encoded];

index += range.length;

}

}

[allowedCharacterSet release];

return escaped;

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,427评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,551评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,747评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,939评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,955评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,737评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,448评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,352评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,834评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,992评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,133评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,815评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,477评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,022评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,147评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,398评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,077评论 2 355

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,671评论 18 139
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,150评论 30 470
  • 1.请简单说明多线程技术的优点和缺点? 优点能适当提高程序的执行效率能适当提高资源的利用率(CPU/内存利用率) ...
    彼岸的黑色曼陀罗阅读 461评论 0 2
  • 1.///消除警告 window Auto property synthesis will not synthes...
    半江瑟瑟阅读 355评论 0 0
  • 经济问题
    祗树阅读 198评论 0 0