OcrUtils.java 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package com.luooqi.ocr.utils;
  2. import cn.hutool.core.codec.Base64;
  3. import cn.hutool.core.lang.UUID;
  4. import cn.hutool.core.util.CharsetUtil;
  5. import cn.hutool.core.util.StrUtil;
  6. import cn.hutool.core.util.URLUtil;
  7. import cn.hutool.crypto.SecureUtil;
  8. import cn.hutool.http.HttpRequest;
  9. import cn.hutool.http.HttpResponse;
  10. import cn.hutool.http.HttpUtil;
  11. import cn.hutool.json.JSONArray;
  12. import cn.hutool.json.JSONObject;
  13. import cn.hutool.json.JSONUtil;
  14. import com.luooqi.ocr.model.TextBlock;
  15. import java.awt.*;
  16. import java.util.*;
  17. import java.util.List;
  18. /**
  19. * tools-ocr
  20. * Created by 何志龙 on 2019-03-22.
  21. */
  22. public class OcrUtils {
  23. public static String ocrImg(byte[] imgData, int ocrType) {
  24. switch (ocrType){
  25. case 0:
  26. return bdGeneralOcr(imgData);
  27. case 1:
  28. return bdAccurateOcr(imgData);
  29. case 2:
  30. return sogouMobileOcr(imgData);
  31. default:
  32. return sogouWebOcr(imgData);
  33. }
  34. }
  35. private static String bdGeneralOcr(byte[] imgData){
  36. return bdBaseOcr(imgData, "general_location");
  37. }
  38. private static String bdAccurateOcr(byte[] imgData){
  39. return bdBaseOcr(imgData, "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate");
  40. }
  41. private static String bdBaseOcr(byte[] imgData, String type){
  42. String[] urlArr = new String[]{"http://ai.baidu.com/tech/ocr/general", "http://ai.baidu.com/index/seccode?action=show"};
  43. StringBuilder cookie = new StringBuilder();
  44. for (String url : urlArr) {
  45. HttpResponse cookieResp = WebUtils.get(url);
  46. List<String> ckList = cookieResp.headerList("Set-Cookie");
  47. for (String s : ckList) {
  48. cookie.append(s.replaceAll("expires[\\S\\s]+", ""));
  49. }
  50. }
  51. HashMap<String, String> header = new HashMap<>();
  52. header.put("Referer", "http://ai.baidu.com/tech/ocr/general");
  53. header.put("Cookie", cookie.toString());
  54. String data = "type="+URLUtil.encodeQuery(type)+"&detect_direction=false&image_url&image=" + URLUtil.encodeQuery("data:image/jpeg;base64," + Base64.encode(imgData)) + "&language_type=CHN_ENG";
  55. HttpResponse response = WebUtils.postRaw("http://ai.baidu.com/aidemo", data, 0, header);
  56. return extractBdResult(WebUtils.getSafeHtml(response));
  57. }
  58. public static String sogouMobileOcr(byte[] imgData) {
  59. String boundary = "------WebKitFormBoundary8orYTmcj8BHvQpVU";
  60. String url = "http://ocr.shouji.sogou.com/v2/ocr/json";
  61. String header = boundary + "\r\nContent-Disposition: form-data; name=\"pic\"; filename=\"pic.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n";
  62. String footer = "\r\n" + boundary + "--\r\n";
  63. byte[] postData = CommUtils.mergeByte(header.getBytes(CharsetUtil.CHARSET_ISO_8859_1), imgData, footer.getBytes(CharsetUtil.CHARSET_ISO_8859_1));
  64. return extractSogouResult(CommUtils.postMultiData(url, postData, boundary.substring(2)));
  65. }
  66. public static String sogouWebOcr(byte[] imgData) {
  67. String url = "https://deepi.sogou.com/api/sogouService";
  68. String referer = "https://deepi.sogou.com/?from=picsearch&tdsourcetag=s_pctim_aiomsg";
  69. String imageData = Base64.encode(imgData);
  70. long t = new Date().getTime();
  71. String sign = SecureUtil.md5("sogou_ocr_just_for_deepibasicOpenOcr" + t + imageData.substring(0, Math.min(1024, imageData.length())) + "7f42cedccd1b3917c87aeb59e08b40ad");
  72. Map<String, Object> data = new HashMap<>();
  73. data.put("image", imageData);
  74. data.put("lang", "zh-Chs");
  75. data.put("pid", "sogou_ocr_just_for_deepi");
  76. data.put("salt", t);
  77. data.put("service", "basicOpenOcr");
  78. data.put("sign", sign);
  79. HttpRequest request = HttpUtil.createPost(url).timeout(15000);
  80. request.form(data);
  81. request.header("Referer", referer);
  82. HttpResponse response = request.execute();
  83. return extractSogouResult(WebUtils.getSafeHtml(response));
  84. }
  85. private static String extractSogouResult(String html) {
  86. if (StrUtil.isBlank(html)) {
  87. return "";
  88. }
  89. JSONObject jsonObject = JSONUtil.parseObj(html);
  90. if (jsonObject.getInt("success", 0) != 1) {
  91. return "";
  92. }
  93. JSONArray jsonArray = jsonObject.getJSONArray("result");
  94. List<TextBlock> textBlocks = new ArrayList<>();
  95. boolean isEng;
  96. for (int i = 0; i < jsonArray.size(); i++) {
  97. JSONObject jObj = jsonArray.getJSONObject(i);
  98. TextBlock textBlock = new TextBlock();
  99. textBlock.setText(jObj.getStr("content").trim());
  100. //noinspection SuspiciousToArrayCall
  101. String[] frames = jObj.getJSONArray("frame").toArray(new String[0]);
  102. textBlock.setTopLeft(CommUtils.frameToPoint(frames[0]));
  103. textBlock.setTopRight(CommUtils.frameToPoint(frames[1]));
  104. textBlock.setBottomRight(CommUtils.frameToPoint(frames[2]));
  105. textBlock.setBottomLeft(CommUtils.frameToPoint(frames[3]));
  106. textBlocks.add(textBlock);
  107. }
  108. isEng = jsonObject.getStr("lang", "zh-Chs").equals("zh-Chs");
  109. return CommUtils.combineTextBlocks(textBlocks, isEng);
  110. }
  111. private static String extractBdResult(String html) {
  112. if (StrUtil.isBlank(html)) {
  113. return "";
  114. }
  115. JSONObject jsonObject = JSONUtil.parseObj(html);
  116. if (jsonObject.getInt("errno", 0) != 0) {
  117. return "";
  118. }
  119. JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("words_result");
  120. List<TextBlock> textBlocks = new ArrayList<>();
  121. boolean isEng = false;
  122. for (int i = 0; i < jsonArray.size(); i++) {
  123. JSONObject jObj = jsonArray.getJSONObject(i);
  124. TextBlock textBlock = new TextBlock();
  125. textBlock.setText(jObj.getStr("words").trim());
  126. //noinspection SuspiciousToArrayCall
  127. JSONObject location = jObj.getJSONObject("location");
  128. int top = location.getInt("top");
  129. int left = location.getInt("left");
  130. int width = location.getInt("width");
  131. int height = location.getInt("height");
  132. textBlock.setTopLeft(new Point(top, left));
  133. textBlock.setTopRight(new Point(top, left + width));
  134. textBlock.setBottomLeft(new Point(top + height, left));
  135. textBlock.setBottomRight(new Point(top + height, left + width));
  136. textBlocks.add(textBlock);
  137. }
  138. return CommUtils.combineTextBlocks(textBlocks, isEng);
  139. }
  140. }