OcrUtils.java 6.8 KB

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