#1235 微信公众号模块增加图像处理接口

* 图像处理二维码识别接口

* 图像处理图像高清化接口

* 公众号图像处理智能裁剪接口
This commit is contained in:
TheoNie 2019-10-16 16:51:03 +08:00 committed by Binary Wang
parent 902ba61e73
commit 829ca6f9e2
9 changed files with 688 additions and 0 deletions

View File

@ -0,0 +1,121 @@
package me.chanjar.weixin.mp.api;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.bean.imgproc.WxMpImgProcAiCropResult;
import me.chanjar.weixin.mp.bean.imgproc.WxMpImgProcQrCodeResult;
import me.chanjar.weixin.mp.bean.imgproc.WxMpImgProcSuperResolutionResult;
import java.io.File;
/**
* 多项图像处理能力相关的API.
* https://developers.weixin.qq.com/doc/offiaccount/Intelligent_Interface/Img_Proc.html
*
* @author Theo Nie
*/
public interface WxMpImgProcService {
/**
* 二维码/条码识别接口
* 说明
* 1.图片支持使用img参数实时上传也支持使用img_url参数传送图片地址由微信后台下载图片进行识别
* 2.文件大小限制小于2M
* 3.支持条码二维码DataMatrix和PDF417的识别
* 4.二维码DataMatrix会返回位置坐标条码和PDF417暂不返回位置坐标
*
* @param imgUrl 图片url地址
* @return WxMpImgProcQrCodeResult
* @throws WxErrorException .
*/
WxMpImgProcQrCodeResult qrCode(String imgUrl) throws WxErrorException;
/**
* 二维码/条码识别接口
* 说明
* 1.图片支持使用img参数实时上传也支持使用img_url参数传送图片地址由微信后台下载图片进行识别
* 2.文件大小限制小于2M
* 3.支持条码二维码DataMatrix和PDF417的识别
* 4.二维码DataMatrix会返回位置坐标条码和PDF417暂不返回位置坐标
*
* @param imgFile 图片文件对象
* @return WxMpImgProcQrCodeResult
* @throws WxErrorException .
*/
WxMpImgProcQrCodeResult qrCode(File imgFile) throws WxErrorException;
/**
* 图片高清化接口
* 说明
* 1.图片支持使用img参数实时上传也支持使用img_url参数传送图片地址由微信后台下载图片进行识别
* 2.文件大小限制小于2M
* 3.目前支持将图片超分辨率高清化2倍即生成图片分辨率为原图2倍大小
* 返回的media_id有效期为3天期间可以通过获取临时素材接口获取图片二进制
*
* @param imgUrl 图片url地址
* @return WxMpImgProcSuperResolutionResult
* @throws WxErrorException .
*/
WxMpImgProcSuperResolutionResult superResolution(String imgUrl) throws WxErrorException;
/**
* 图片高清化接口
* 说明
* 1.图片支持使用img参数实时上传也支持使用img_url参数传送图片地址由微信后台下载图片进行识别
* 2.文件大小限制小于2M
* 3.目前支持将图片超分辨率高清化2倍即生成图片分辨率为原图2倍大小
* 返回的media_id有效期为3天期间可以通过获取临时素材接口获取图片二进制
*
* @param imgFile 图片文件对象
* @return WxMpImgProcSuperResolutionResult
* @throws WxErrorException .
*/
WxMpImgProcSuperResolutionResult superResolution(File imgFile) throws WxErrorException;
/**
* 图片智能裁剪接口
* 说明
* 1.图片支持使用img参数实时上传也支持使用img_url参数传送图片地址由微信后台下载图片进行识别
* 2.文件大小限制小于2M
* 3.该接口默认使用最佳宽高比
* @param imgUrl 图片url地址
* @return WxMpImgProcAiCropResult
* @throws WxErrorException .
*/
WxMpImgProcAiCropResult aiCrop(String imgUrl) throws WxErrorException;
/**
* 图片智能裁剪接口
* 说明
* 1.图片支持使用img参数实时上传也支持使用img_url参数传送图片地址由微信后台下载图片进行识别
* 2.文件大小限制小于2M
* @param imgUrl 图片url地址
* @param ratios 宽高比最多支持5个请以英文逗号分隔
* @return WxMpImgProcAiCropResult
* @throws WxErrorException .
*/
WxMpImgProcAiCropResult aiCrop(String imgUrl, String ratios) throws WxErrorException;
/**
* 图片智能裁剪接口
* 说明
* 1.图片支持使用img参数实时上传也支持使用img_url参数传送图片地址由微信后台下载图片进行识别
* 2.文件大小限制小于2M
* 3.该接口默认使用最佳宽高比
* @param imgFile 图片文件对象
* @return WxMpImgProcAiCropResult
* @throws WxErrorException .
*/
WxMpImgProcAiCropResult aiCrop(File imgFile) throws WxErrorException;
/**
* 图片智能裁剪接口
* 说明
* 1.图片支持使用img参数实时上传也支持使用img_url参数传送图片地址由微信后台下载图片进行识别
* 2.文件大小限制小于2M
* @param imgFile 图片文件对象
* @param ratios 宽高比最多支持5个请以英文逗号分隔
* @return WxMpImgProcAiCropResult
* @throws WxErrorException .
*/
WxMpImgProcAiCropResult aiCrop(File imgFile, String ratios) throws WxErrorException;
}

View File

@ -522,6 +522,12 @@ public interface WxMpService {
*/
WxMpOcrService getOcrService();
/**
* 返回图像处理接口的实现类对象以方便调用其各个接口.
* @return WxMpImgProcService
*/
WxMpImgProcService getImgProcService();
/**
* .
*
@ -648,6 +654,13 @@ public interface WxMpService {
*/
void setOcrService(WxMpOcrService ocrService);
/**
* .
*
* @param imgProcService .
*/
void setImgProcService(WxMpImgProcService imgProcService);
/**
* 返回评论数据管理接口方法的实现类对象以方便调用其各个接口.
*

View File

@ -67,6 +67,7 @@ public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestH
private WxMpMarketingService marketingService = new WxMpMarketingServiceImpl(this);
private WxMpCommentService commentService = new WxMpCommentServiceImpl(this);
private WxMpOcrService ocrService = new WxMpOcrServiceImpl(this);
private WxMpImgProcService imgProcService = new WxMpImgProcServiceImpl(this);
private Map<String, WxMpConfigStorage> configStorageMap;
@ -647,4 +648,14 @@ public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestH
public void setCommentService(WxMpCommentService commentService) {
this.commentService = commentService;
}
@Override
public WxMpImgProcService getImgProcService() {
return this.imgProcService;
}
@Override
public void setImgProcService(WxMpImgProcService imgProcService) {
this.imgProcService = imgProcService;
}
}

View File

@ -0,0 +1,104 @@
package me.chanjar.weixin.mp.api.impl;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpImgProcService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.imgproc.WxMpImgProcAiCropResult;
import me.chanjar.weixin.mp.bean.imgproc.WxMpImgProcQrCodeResult;
import me.chanjar.weixin.mp.bean.imgproc.WxMpImgProcSuperResolutionResult;
import me.chanjar.weixin.mp.util.requestexecuter.ocr.OcrDiscernRequestExecutor;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.ImgProc.AI_CROP;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.ImgProc.FILE_AI_CROP;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.ImgProc.FILE_QRCODE;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.ImgProc.FILE_SUPER_RESOLUTION;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.ImgProc.QRCODE;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.ImgProc.SUPER_RESOLUTION;
/**
* 图像处理接口实现.
* @author Theo Nie
*/
@RequiredArgsConstructor
public class WxMpImgProcServiceImpl implements WxMpImgProcService {
private final WxMpService wxMpService;
@Override
public WxMpImgProcQrCodeResult qrCode(String imgUrl) throws WxErrorException {
try {
imgUrl = URLEncoder.encode(imgUrl, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
//ignore
}
final String result = this.wxMpService.get(String.format(QRCODE.getUrl(this.wxMpService.getWxMpConfigStorage()), imgUrl), null);
return WxMpImgProcQrCodeResult.fromJson(result);
}
@Override
public WxMpImgProcQrCodeResult qrCode(File imgFile) throws WxErrorException {
String result = this.wxMpService.execute(OcrDiscernRequestExecutor.create(this.wxMpService.getRequestHttp()), FILE_QRCODE.getUrl(this.wxMpService.getWxMpConfigStorage()), imgFile);
return WxMpImgProcQrCodeResult.fromJson(result);
}
@Override
public WxMpImgProcSuperResolutionResult superResolution(String imgUrl) throws WxErrorException {
try {
imgUrl = URLEncoder.encode(imgUrl, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
//ignore
}
final String result = this.wxMpService.get(String.format(SUPER_RESOLUTION.getUrl(this.wxMpService.getWxMpConfigStorage()), imgUrl), null);
return WxMpImgProcSuperResolutionResult.fromJson(result);
}
@Override
public WxMpImgProcSuperResolutionResult superResolution(File imgFile) throws WxErrorException {
String result = this.wxMpService.execute(OcrDiscernRequestExecutor.create(this.wxMpService.getRequestHttp()), FILE_SUPER_RESOLUTION.getUrl(this.wxMpService.getWxMpConfigStorage()), imgFile);
return WxMpImgProcSuperResolutionResult.fromJson(result);
}
@Override
public WxMpImgProcAiCropResult aiCrop(String imgUrl) throws WxErrorException {
return this.aiCrop(imgUrl, "");
}
@Override
public WxMpImgProcAiCropResult aiCrop(String imgUrl, String ratios) throws WxErrorException {
try {
imgUrl = URLEncoder.encode(imgUrl, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
//ignore
}
if (StringUtils.isEmpty(ratios)) {
ratios = "";
}
final String result = this.wxMpService.get(String.format(AI_CROP.getUrl(this.wxMpService.getWxMpConfigStorage()), imgUrl, ratios), null);
return WxMpImgProcAiCropResult.fromJson(result);
}
@Override
public WxMpImgProcAiCropResult aiCrop(File imgFile) throws WxErrorException {
return this.aiCrop(imgFile, "");
}
@Override
public WxMpImgProcAiCropResult aiCrop(File imgFile, String ratios) throws WxErrorException {
if (StringUtils.isEmpty(ratios)) {
ratios = "";
}
String result = this.wxMpService.execute(OcrDiscernRequestExecutor.create(this.wxMpService.getRequestHttp()), String.format(FILE_AI_CROP.getUrl(this.wxMpService.getWxMpConfigStorage()), ratios), imgFile);
return WxMpImgProcAiCropResult.fromJson(result);
}
}

View File

@ -0,0 +1,60 @@
package me.chanjar.weixin.mp.bean.imgproc;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import java.io.Serializable;
import java.util.List;
/**
* @author Theo Nie
*/
@Data
public class WxMpImgProcAiCropResult implements Serializable {
private static final long serialVersionUID = -6470673963772979463L;
@SerializedName("img_size")
private ImgSize imgSize;
@SerializedName("results")
private List<Results> results;
@Override
public String toString() {
return WxMpGsonBuilder.create().toJson(this);
}
public static WxMpImgProcAiCropResult fromJson(String json) {
return WxMpGsonBuilder.create().fromJson(json, WxMpImgProcAiCropResult.class);
}
@Data
public static class ImgSize {
@SerializedName("w")
private int w;
@SerializedName("h")
private int h;
@Override
public String toString() {
return WxMpGsonBuilder.create().toJson(this);
}
}
@Data
public static class Results {
@SerializedName("crop_left")
private int cropLeft;
@SerializedName("crop_top")
private int cropTop;
@SerializedName("crop_right")
private int cropRight;
@SerializedName("crop_bottom")
private int cropBottom;
@Override
public String toString() {
return WxMpGsonBuilder.create().toJson(this);
}
}
}

View File

@ -0,0 +1,93 @@
package me.chanjar.weixin.mp.bean.imgproc;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import java.io.Serializable;
import java.util.List;
/**
* 二维码/条码识别返回结果
* @author Theo Nie
*/
@Data
public class WxMpImgProcQrCodeResult implements Serializable {
private static final long serialVersionUID = -1194154790100866123L;
@SerializedName("img_size")
private ImgSize imgSize;
@SerializedName("code_results")
private List<CodeResults> codeResults;
@Data
public static class ImgSize implements Serializable{
private static final long serialVersionUID = -8847603245514017839L;
@SerializedName("w")
private int w;
@SerializedName("h")
private int h;
@Override
public String toString() {
return WxMpGsonBuilder.create().toJson(this);
}
}
@Data
public static class CodeResults implements Serializable{
private static final long serialVersionUID = -6138135951229076759L;
@SerializedName("type_name")
private String typeName;
@SerializedName("data")
private String data;
@SerializedName("pos")
private Pos pos;
@Override
public String toString() {
return WxMpGsonBuilder.create().toJson(this);
}
@Data
public static class Pos implements Serializable{
private static final long serialVersionUID = 7754894061212819602L;
@SerializedName("left_top")
private Coordinate leftTop;
@SerializedName("right_top")
private Coordinate rightTop;
@SerializedName("right_bottom")
private Coordinate rightBottom;
@SerializedName("left_bottom")
private Coordinate leftBottom;
@Override
public String toString() {
return WxMpGsonBuilder.create().toJson(this);
}
@Data
public static class Coordinate implements Serializable{
private static final long serialVersionUID = 8930443668927359677L;
@SerializedName("x")
private int x;
@SerializedName("y")
private int y;
@Override
public String toString() {
return WxMpGsonBuilder.create().toJson(this);
}
}
}
}
public static WxMpImgProcQrCodeResult fromJson(String json) {
return WxMpGsonBuilder.create().fromJson(json, WxMpImgProcQrCodeResult.class);
}
@Override
public String toString() {
return WxMpGsonBuilder.create().toJson(this);
}
}

View File

@ -0,0 +1,28 @@
package me.chanjar.weixin.mp.bean.imgproc;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import java.io.Serializable;
/**
* 图片高清化返回结果
* @author Theo Nie
*/
@Data
public class WxMpImgProcSuperResolutionResult implements Serializable {
private static final long serialVersionUID = 8007440280170407021L;
@SerializedName("media_id")
private String mediaId;
@Override
public String toString() {
return WxMpGsonBuilder.create().toJson(this);
}
public static WxMpImgProcSuperResolutionResult fromJson(String json) {
return WxMpGsonBuilder.create().fromJson(json, WxMpImgProcSuperResolutionResult.class);
}
}

View File

@ -954,4 +954,49 @@ public interface WxMpApiUrl {
return buildUrl(config.getHostConfig(), prefix, path);
}
}
@AllArgsConstructor
enum ImgProc implements WxMpApiUrl {
/**
* 二维码/条码识别
*/
QRCODE(API_DEFAULT_HOST_URL, "/cv/img/qrcode?img_url=%s"),
/**
* 二维码/条码识别(文件)
*/
FILE_QRCODE(API_DEFAULT_HOST_URL, "/cv/img/qrcode"),
/**
* 图片高清化
*/
SUPER_RESOLUTION(API_DEFAULT_HOST_URL, "/cv/img/superresolution?img_url=%s"),
/**
* 图片高清化(文件)
*/
FILE_SUPER_RESOLUTION(API_DEFAULT_HOST_URL, "/cv/img/superresolution"),
/**
* 图片智能裁剪
*/
AI_CROP(API_DEFAULT_HOST_URL, "/cv/img/aicrop?img_url=%s&ratios=%s"),
/**
* 图片智能裁剪(文件)
*/
FILE_AI_CROP(API_DEFAULT_HOST_URL, "/cv/img/aicrop?ratios=%s");
private String prefix;
private String path;
@Override
public String getUrl(WxMpConfigStorage config) {
if (null == config) {
return buildUrl(null, prefix, path);
}
return buildUrl(config.getHostConfig(), prefix, path);
}
}
}

View File

@ -0,0 +1,213 @@
package me.chanjar.weixin.mp.api.impl;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.fs.FileUtils;
import me.chanjar.weixin.mp.api.WxMpImgProcService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.test.ApiTestModule;
import me.chanjar.weixin.mp.api.test.TestConstants;
import me.chanjar.weixin.mp.bean.imgproc.WxMpImgProcAiCropResult;
import me.chanjar.weixin.mp.bean.imgproc.WxMpImgProcQrCodeResult;
import me.chanjar.weixin.mp.bean.imgproc.WxMpImgProcSuperResolutionResult;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import javax.inject.Inject;
import java.io.File;
import java.io.InputStream;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;
@Test
@Guice(modules = ApiTestModule.class)
public class WxMpImgProcServiceImplTest {
@Inject
private WxMpService mpService;
@Test
public void testQrCode() throws WxErrorException {
final WxMpImgProcQrCodeResult result = this.mpService.getImgProcService().qrCode("https://gitee.com/binary/weixin-java-tools/raw/master/images/qrcodes/mp.png");
assertThat(result).isNotNull();
System.out.println(result);
}
@Test
public void testQrCode2() throws Exception {
InputStream inputStream = ClassLoader.getSystemResourceAsStream("mm.jpeg");
File tempFile = FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), TestConstants.FILE_JPG);
final WxMpImgProcQrCodeResult result = this.mpService.getImgProcService().qrCode(tempFile);
assertThat(result).isNotNull();
System.out.println(result);
}
@Test
public void testSuperResolution() throws WxErrorException {
final WxMpImgProcSuperResolutionResult result = this.mpService.getImgProcService().superResolution("https://gitee.com/binary/weixin-java-tools/raw/master/images/qrcodes/mp.png");
assertThat(result).isNotNull();
System.out.println(result);
}
@Test
public void testSuperResolution2() throws Exception {
InputStream inputStream = ClassLoader.getSystemResourceAsStream("mm.jpeg");
File tempFile = FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), TestConstants.FILE_JPG);
final WxMpImgProcSuperResolutionResult result = this.mpService.getImgProcService().superResolution(tempFile);
assertThat(result).isNotNull();
System.out.println(result);
}
@Test
public void testAiCrop() throws WxErrorException {
final WxMpImgProcAiCropResult result = this.mpService.getImgProcService().aiCrop("https://gitee.com/binary/weixin-java-tools/raw/master/images/qrcodes/mp.png");
assertThat(result).isNotNull();
System.out.println(result);
}
@Test
public void testAiCrop2() throws WxErrorException {
final WxMpImgProcAiCropResult result = this.mpService.getImgProcService().aiCrop("https://gitee.com/binary/weixin-java-tools/raw/master/images/qrcodes/mp.png", "1,2.35");
assertThat(result).isNotNull();
System.out.println(result);
}
@Test
public void testAiCrop3() throws Exception {
InputStream inputStream = ClassLoader.getSystemResourceAsStream("mm.jpeg");
File tempFile = FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), TestConstants.FILE_JPG);
final WxMpImgProcAiCropResult result = this.mpService.getImgProcService().aiCrop(tempFile);
assertThat(result).isNotNull();
System.out.println(result);
}
@Test
public void testAiCrop4() throws Exception {
InputStream inputStream = ClassLoader.getSystemResourceAsStream("mm.jpeg");
File tempFile = FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), TestConstants.FILE_JPG);
final WxMpImgProcAiCropResult result = this.mpService.getImgProcService().aiCrop(tempFile, "1,2.35,3.5");
assertThat(result).isNotNull();
System.out.println(result);
}
public static class mockTest {
private WxMpService wxService = mock(WxMpService.class);
@Test
public void testQrCode() throws Exception {
String returnJson = "{\n" +
" \"errcode\": 0, \n" +
" \"errmsg\": \"ok\", \n" +
" \"code_results\": [\n" +
" {\n" +
" \"type_name\": \"QR_CODE\", \n" +
" \"data\": \"https://www.qq.com\", \n" +
" \"pos\": {\n" +
" \"left_top\": {\n" +
" \"x\": 585, \n" +
" \"y\": 378\n" +
" }, \n" +
" \"right_top\": {\n" +
" \"x\": 828, \n" +
" \"y\": 378\n" +
" }, \n" +
" \"right_bottom\": {\n" +
" \"x\": 828, \n" +
" \"y\": 618\n" +
" }, \n" +
" \"left_bottom\": {\n" +
" \"x\": 585, \n" +
" \"y\": 618\n" +
" }\n" +
" }\n" +
" }, \n" +
" {\n" +
" \"type_name\": \"QR_CODE\", \n" +
" \"data\": \"https://mp.weixin.qq.com\", \n" +
" \"pos\": {\n" +
" \"left_top\": {\n" +
" \"x\": 185, \n" +
" \"y\": 142\n" +
" }, \n" +
" \"right_top\": {\n" +
" \"x\": 396, \n" +
" \"y\": 142\n" +
" }, \n" +
" \"right_bottom\": {\n" +
" \"x\": 396, \n" +
" \"y\": 353\n" +
" }, \n" +
" \"left_bottom\": {\n" +
" \"x\": 185, \n" +
" \"y\": 353\n" +
" }\n" +
" }\n" +
" }, \n" +
" {\n" +
" \"type_name\": \"EAN_13\", \n" +
" \"data\": \"5906789678957\"\n" +
" }, \n" +
" {\n" +
" \"type_name\": \"CODE_128\", \n" +
" \"data\": \"50090500019191\"\n" +
" }\n" +
" ], \n" +
" \"img_size\": {\n" +
" \"w\": 1000, \n" +
" \"h\": 900\n" +
" }\n" +
"}";
when(wxService.get(anyString(), anyString())).thenReturn(returnJson);
final WxMpImgProcService wxMpImgProcService = new WxMpImgProcServiceImpl(wxService);
final WxMpImgProcQrCodeResult result = wxMpImgProcService.qrCode("abc");
assertThat(result).isNotNull();
System.out.println(result);
}
@Test
public void testSuperResolution() throws Exception {
String returnJson = "{\n" +
" \"errcode\": 0, \n" +
" \"errmsg\": \"ok\", \n" +
" \"media_id\": \"6WXsIXkG7lXuDLspD9xfm5dsvHzb0EFl0li6ySxi92ap8Vl3zZoD9DpOyNudeJGB\"\n" +
"}";
when(wxService.get(anyString(), anyString())).thenReturn(returnJson);
final WxMpImgProcService wxMpImgProcService = new WxMpImgProcServiceImpl(wxService);
final WxMpImgProcSuperResolutionResult result = wxMpImgProcService.superResolution("abc");
assertThat(result).isNotNull();
System.out.println(result);
}
@Test
public void testAiCrop() throws Exception {
String returnJson = "{\n" +
" \"errcode\": 0, \n" +
" \"errmsg\": \"ok\", \n" +
" \"results\": [ //智能裁剪结果\n" +
" {\n" +
" \"crop_left\": 112, \n" +
" \"crop_top\": 0, \n" +
" \"crop_right\": 839, \n" +
" \"crop_bottom\": 727\n" +
" }, \n" +
" {\n" +
" \"crop_left\": 0, \n" +
" \"crop_top\": 205, \n" +
" \"crop_right\": 965, \n" +
" \"crop_bottom\": 615\n" +
" }\n" +
" ], \n" +
" \"img_size\": { //图片大小\n" +
" \"w\": 966, \n" +
" \"h\": 728\n" +
" }\n" +
"}";
when(wxService.get(anyString(), anyString())).thenReturn(returnJson);
final WxMpImgProcService wxMpImgProcService = new WxMpImgProcServiceImpl(wxService);
final WxMpImgProcAiCropResult result = wxMpImgProcService.aiCrop("abc");
assertThat(result).isNotNull();
System.out.println(result);
}
}
}