diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpImgProcService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpImgProcService.java new file mode 100644 index 000000000..63cea28e7 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpImgProcService.java @@ -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; +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index 069175dee..2d95b4f4e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -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); + /** * 返回评论数据管理接口方法的实现类对象,以方便调用其各个接口. * diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java index c44993052..e57099e9d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java @@ -67,6 +67,7 @@ public abstract class BaseWxMpServiceImpl 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 configStorageMap; @@ -647,4 +648,14 @@ public abstract class BaseWxMpServiceImpl 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; + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpImgProcServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpImgProcServiceImpl.java new file mode 100644 index 000000000..8f59a8f16 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpImgProcServiceImpl.java @@ -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); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/imgproc/WxMpImgProcAiCropResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/imgproc/WxMpImgProcAiCropResult.java new file mode 100644 index 000000000..ef25670d9 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/imgproc/WxMpImgProcAiCropResult.java @@ -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; + + @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); + } + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/imgproc/WxMpImgProcQrCodeResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/imgproc/WxMpImgProcQrCodeResult.java new file mode 100644 index 000000000..a897e7f60 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/imgproc/WxMpImgProcQrCodeResult.java @@ -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; + + @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); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/imgproc/WxMpImgProcSuperResolutionResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/imgproc/WxMpImgProcSuperResolutionResult.java new file mode 100644 index 000000000..b9d78f4f2 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/imgproc/WxMpImgProcSuperResolutionResult.java @@ -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); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java index 5a10dea48..df62324d7 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java @@ -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); + } + } + } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpImgProcServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpImgProcServiceImplTest.java new file mode 100644 index 000000000..37f6ab722 --- /dev/null +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpImgProcServiceImplTest.java @@ -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); + } + } +}