Skip to content

Commit c3e5f0f

Browse files
authored
实现OCR菜单识别接口(cv/ocr/menu)
- 新增 WxOcrMenuResult Bean(weixin-java-common) - 在 WxOcrService 接口中添加 menu(String) 和 menu(File) 方法 - 在 WxMpApiUrl.Ocr 枚举中添加 MENU 和 FILE_MENU URL - 在 WxMpOcrServiceImpl 中实现 menu 方法 - 在 WxMaApiUrlConstants.Ocr 中添加菜单识别URL常量 - 在 WxMaOcrServiceImpl 中实现 menu 方法 - 在 WxMpOcrServiceImplTest 中添加 testMenu 和 testMenu2 测试用例
1 parent edd94cd commit c3e5f0f

7 files changed

Lines changed: 176 additions & 1 deletion

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package me.chanjar.weixin.common.bean.ocr;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
import lombok.Data;
5+
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
6+
7+
import java.io.Serializable;
8+
import java.util.List;
9+
10+
/**
11+
* OCR菜单识别结果.
12+
*
13+
* @author GitHub Copilot
14+
*/
15+
@Data
16+
public class WxOcrMenuResult implements Serializable {
17+
private static final long serialVersionUID = -8062516251827437945L;
18+
19+
@SerializedName("img_size")
20+
private WxOcrImgSize imgSize;
21+
@SerializedName("items")
22+
private List<Items> items;
23+
24+
public static WxOcrMenuResult fromJson(String json) {
25+
return WxGsonBuilder.create().fromJson(json, WxOcrMenuResult.class);
26+
}
27+
28+
@Override
29+
public String toString() {
30+
return WxGsonBuilder.create().toJson(this);
31+
}
32+
33+
@Data
34+
public static class Items implements Serializable {
35+
private static final long serialVersionUID = 3066181677009102792L;
36+
37+
@SerializedName("text")
38+
private String text;
39+
@SerializedName("pos")
40+
private WxOcrPos pos;
41+
42+
@Override
43+
public String toString() {
44+
return WxGsonBuilder.create().toJson(this);
45+
}
46+
}
47+
}

weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOcrService.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import me.chanjar.weixin.common.bean.ocr.WxOcrDrivingLicenseResult;
88
import me.chanjar.weixin.common.bean.ocr.WxOcrDrivingResult;
99
import me.chanjar.weixin.common.bean.ocr.WxOcrIdCardResult;
10+
import me.chanjar.weixin.common.bean.ocr.WxOcrMenuResult;
1011

1112
import java.io.File;
1213

@@ -130,4 +131,22 @@ public interface WxOcrService {
130131
* @throws WxErrorException .
131132
*/
132133
WxOcrCommResult comm(File imgFile) throws WxErrorException;
134+
135+
/**
136+
* 菜单OCR识别接口
137+
* 文件大小限制:小于2M
138+
* @param imgUrl 图片url地址
139+
* @return WxOcrMenuResult
140+
* @throws WxErrorException .
141+
*/
142+
WxOcrMenuResult menu(String imgUrl) throws WxErrorException;
143+
144+
/**
145+
* 菜单OCR识别接口
146+
* 文件大小限制:小于2M
147+
* @param imgFile 图片文件对象
148+
* @return WxOcrMenuResult
149+
* @throws WxErrorException .
150+
*/
151+
WxOcrMenuResult menu(File imgFile) throws WxErrorException;
133152
}

weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaOcrServiceImpl.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,23 @@ public WxOcrCommResult comm(File imgFile) throws WxErrorException {
138138
FILE_COMM, imgFile);
139139
return WxOcrCommResult.fromJson(result);
140140
}
141+
142+
@Override
143+
public WxOcrMenuResult menu(String imgUrl) throws WxErrorException {
144+
try {
145+
imgUrl = URLEncoder.encode(imgUrl, StandardCharsets.UTF_8.name());
146+
} catch (UnsupportedEncodingException e) {
147+
// ignore cannot happen
148+
}
149+
150+
final String result = this.service.post(String.format(MENU, imgUrl), (String) null);
151+
return WxOcrMenuResult.fromJson(result);
152+
}
153+
154+
@Override
155+
public WxOcrMenuResult menu(File imgFile) throws WxErrorException {
156+
String result = this.service.execute(OcrDiscernRequestExecutor.create(this.service.getRequestHttp()),
157+
FILE_MENU, imgFile);
158+
return WxOcrMenuResult.fromJson(result);
159+
}
141160
}

weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,8 @@ public interface Ocr {
393393
String FILE_BIZ_LICENSE = "https://api.weixin.qq.com/cv/ocr/bizlicense";
394394
String COMM = "https://api.weixin.qq.com/cv/ocr/comm?img_url=%s";
395395
String FILE_COMM = "https://api.weixin.qq.com/cv/ocr/comm";
396+
String MENU = "https://api.weixin.qq.com/cv/ocr/menu?img_url=%s";
397+
String FILE_MENU = "https://api.weixin.qq.com/cv/ocr/menu";
396398
}
397399

398400
public interface Product {

weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpOcrServiceImpl.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,24 @@ public WxOcrCommResult comm(File imgFile) throws WxErrorException {
143143
FILE_COMM.getUrl(this.mainService.getWxMpConfigStorage()), imgFile);
144144
return WxOcrCommResult.fromJson(result);
145145
}
146+
147+
@Override
148+
public WxOcrMenuResult menu(String imgUrl) throws WxErrorException {
149+
try {
150+
imgUrl = URLEncoder.encode(imgUrl, StandardCharsets.UTF_8.name());
151+
} catch (UnsupportedEncodingException e) {
152+
// ignore cannot happen
153+
}
154+
155+
final String result = this.mainService.post(String.format(MENU.getUrl(this.mainService.getWxMpConfigStorage()),
156+
imgUrl), (String) null);
157+
return WxOcrMenuResult.fromJson(result);
158+
}
159+
160+
@Override
161+
public WxOcrMenuResult menu(File imgFile) throws WxErrorException {
162+
String result = this.mainService.execute(OcrDiscernRequestExecutor.create(this.mainService.getRequestHttp()),
163+
FILE_MENU.getUrl(this.mainService.getWxMpConfigStorage()), imgFile);
164+
return WxOcrMenuResult.fromJson(result);
165+
}
146166
}

weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,17 @@ enum Ocr implements WxMpApiUrl {
533533
/**
534534
* 通用印刷体OCR识别(文件)
535535
*/
536-
FILE_COMM(API_DEFAULT_HOST_URL, "/cv/ocr/comm");
536+
FILE_COMM(API_DEFAULT_HOST_URL, "/cv/ocr/comm"),
537+
538+
/**
539+
* 菜单OCR识别
540+
*/
541+
MENU(API_DEFAULT_HOST_URL, "/cv/ocr/menu?img_url=%s"),
542+
543+
/**
544+
* 菜单OCR识别(文件)
545+
*/
546+
FILE_MENU(API_DEFAULT_HOST_URL, "/cv/ocr/menu");
537547

538548
private final String prefix;
539549
private final String path;

weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpOcrServiceImplTest.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import me.chanjar.weixin.common.bean.ocr.WxOcrDrivingLicenseResult;
1212
import me.chanjar.weixin.common.bean.ocr.WxOcrDrivingResult;
1313
import me.chanjar.weixin.common.bean.ocr.WxOcrIdCardResult;
14+
import me.chanjar.weixin.common.bean.ocr.WxOcrMenuResult;
1415
import org.testng.annotations.Guice;
1516
import org.testng.annotations.Test;
1617

@@ -137,6 +138,22 @@ public void testComm2() throws Exception {
137138
System.out.println(result);
138139
}
139140

141+
@Test
142+
public void testMenu() throws WxErrorException {
143+
final WxOcrMenuResult result = this.service.getOcrService().menu("https://res.wx.qq.com/op_res/apCy0YbnEdjYsa_cjW6x3FlpCc20uQ-2BYE7aXnFsrB-ALHZNgdKXhzIUcrRnDoL");
144+
assertThat(result).isNotNull();
145+
System.out.println(result);
146+
}
147+
148+
@Test
149+
public void testMenu2() throws Exception {
150+
InputStream inputStream = ClassLoader.getSystemResourceAsStream("mm.jpeg");
151+
File tempFile = FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), TestConstants.FILE_JPG);
152+
final WxOcrMenuResult result = this.service.getOcrService().menu(tempFile);
153+
assertThat(result).isNotNull();
154+
System.out.println(result);
155+
}
156+
140157
private InputStream getImageStream(String url) {
141158
try {
142159
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
@@ -390,5 +407,46 @@ public void testComm() throws Exception {
390407
assertThat(result).isNotNull();
391408
System.out.println(result);
392409
}
410+
411+
@Test
412+
public void testMenu() throws Exception {
413+
String returnJson = "{\n" +
414+
" \"errcode\": 0, \n" +
415+
" \"errmsg\": \"ok\", \n" +
416+
" \"items\": [\n" +
417+
" {\n" +
418+
" \"text\": \"红烧肉\", \n" +
419+
" \"pos\": {\n" +
420+
" \"left_top\": {\n" +
421+
" \"x\": 575, \n" +
422+
" \"y\": 519\n" +
423+
" }, \n" +
424+
" \"right_top\": {\n" +
425+
" \"x\": 744, \n" +
426+
" \"y\": 519\n" +
427+
" }, \n" +
428+
" \"right_bottom\": {\n" +
429+
" \"x\": 744, \n" +
430+
" \"y\": 532\n" +
431+
" }, \n" +
432+
" \"left_bottom\": {\n" +
433+
" \"x\": 573, \n" +
434+
" \"y\": 532\n" +
435+
" }\n" +
436+
" }\n" +
437+
" }\n" +
438+
" ], \n" +
439+
" \"img_size\": {\n" +
440+
" \"w\": 1280, \n" +
441+
" \"h\": 720\n" +
442+
" }\n" +
443+
"}";
444+
when(wxService.post(anyString(), anyString())).thenReturn(returnJson);
445+
final WxMpOcrServiceImpl wxMpOcrService = new WxMpOcrServiceImpl(wxService);
446+
447+
final WxOcrMenuResult result = wxMpOcrService.menu("abc");
448+
assertThat(result).isNotNull();
449+
System.out.println(result);
450+
}
393451
}
394452
}

0 commit comments

Comments
 (0)