You've already forked FrameTour-BE
feat(facebody): 添加图片下载及base64重试机制
- 当添加人脸因无法访问URL图片失败时,自动下载图片并转换为base64后重试 - 新增downloadImageAsBase64方法用于图片下载与编码 - 替换阿里云OSS域名以支持内网访问 - 增加对png和jpg格式图片的支持 - 使用hutool库进行base64编码 - 添加详细的日志记录以便追踪重试过程
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package com.ycwl.basic.facebody.adapter;
|
package com.ycwl.basic.facebody.adapter;
|
||||||
|
|
||||||
|
import cn.hutool.core.codec.Base64;
|
||||||
import com.baidu.aip.face.AipFace;
|
import com.baidu.aip.face.AipFace;
|
||||||
import com.ycwl.basic.facebody.entity.AddFaceResp;
|
import com.ycwl.basic.facebody.entity.AddFaceResp;
|
||||||
import com.ycwl.basic.facebody.entity.BceFaceBodyConfig;
|
import com.ycwl.basic.facebody.entity.BceFaceBodyConfig;
|
||||||
@@ -15,8 +16,13 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -152,10 +158,34 @@ public class BceFaceBodyAdapter implements IFaceBodyAdapter {
|
|||||||
} catch (InterruptedException ignored) {
|
} catch (InterruptedException ignored) {
|
||||||
}
|
}
|
||||||
JSONObject response = client.addUser(faceUrl, "URL", dbName, entityId, options);
|
JSONObject response = client.addUser(faceUrl, "URL", dbName, entityId, options);
|
||||||
if (response.getInt("error_code") == 0) {
|
int errorCode = response.getInt("error_code");
|
||||||
|
if (errorCode == 0) {
|
||||||
AddFaceResp resp = new AddFaceResp();
|
AddFaceResp resp = new AddFaceResp();
|
||||||
resp.setScore(100f);
|
resp.setScore(100f);
|
||||||
return resp;
|
return resp;
|
||||||
|
} else if (errorCode == 222204) {
|
||||||
|
// error_code: 222204 表示无法正常访问URL图片,尝试下载并转换为base64后重试
|
||||||
|
log.warn("无法正常访问URL图片,错误码: 222204,尝试下载图片转base64后重试,URL: {}", faceUrl);
|
||||||
|
String base64Image = downloadImageAsBase64(faceUrl);
|
||||||
|
if (base64Image != null) {
|
||||||
|
try {
|
||||||
|
addEntityLimiter.acquire();
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
|
JSONObject retryResponse = client.addUser(base64Image, "BASE64", dbName, entityId, options);
|
||||||
|
if (retryResponse.getInt("error_code") == 0) {
|
||||||
|
log.info("使用base64重试添加人脸成功,entityId: {}", entityId);
|
||||||
|
AddFaceResp resp = new AddFaceResp();
|
||||||
|
resp.setScore(100f);
|
||||||
|
return resp;
|
||||||
|
} else {
|
||||||
|
log.warn("使用base64重试添加人脸仍失败!{}", retryResponse);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error("下载图片转base64失败,无法重试,URL: {}", faceUrl);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.warn("创建人脸失败!{}", response);
|
log.warn("创建人脸失败!{}", response);
|
||||||
return null;
|
return null;
|
||||||
@@ -395,7 +425,53 @@ public class BceFaceBodyAdapter implements IFaceBodyAdapter {
|
|||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载图片并转换为base64字符串
|
||||||
|
*
|
||||||
|
* @param imageUrl 图片URL
|
||||||
|
* @return base64编码的图片字符串,失败返回null
|
||||||
|
*/
|
||||||
|
private String downloadImageAsBase64(String imageUrl) {
|
||||||
|
BufferedImage image = null;
|
||||||
|
ByteArrayOutputStream baos = null;
|
||||||
|
try {
|
||||||
|
// 下载图片
|
||||||
|
URL url = new URL(imageUrl.replace("oss-cn-shanghai.aliyuncs.com", "oss-cn-shanghai-internal.aliyuncs.com"));
|
||||||
|
image = ImageIO.read(url);
|
||||||
|
if (image == null) {
|
||||||
|
log.error("无法读取图片,URL: {}", imageUrl);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换为字节数组
|
||||||
|
baos = new ByteArrayOutputStream();
|
||||||
|
String format = "jpg";
|
||||||
|
if (imageUrl.toLowerCase().endsWith(".png")) {
|
||||||
|
format = "png";
|
||||||
|
}
|
||||||
|
ImageIO.write(image, format, baos);
|
||||||
|
byte[] imageBytes = baos.toByteArray();
|
||||||
|
|
||||||
|
// 编码为base64
|
||||||
|
return Base64.encode(imageBytes);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("下载图片或转换base64失败,URL: {}", imageUrl, e);
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
if (image != null) {
|
||||||
|
image.flush();
|
||||||
|
}
|
||||||
|
if (baos != null) {
|
||||||
|
try {
|
||||||
|
baos.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("关闭ByteArrayOutputStream失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private IRateLimiter getLimiter(LOCK_TYPE type) {
|
private IRateLimiter getLimiter(LOCK_TYPE type) {
|
||||||
return switch (type) {
|
return switch (type) {
|
||||||
case ADD_DB ->
|
case ADD_DB ->
|
||||||
|
|||||||
Reference in New Issue
Block a user