Merge remote-tracking branch 'origin/main' into main

This commit is contained in:
马三炮 2025-08-14 11:12:37 +08:00
commit 7488c197d6
8 changed files with 544 additions and 1 deletions

View File

@ -0,0 +1,244 @@
package com.bonus.common.core.utils.face;
import com.arcsoft.face.*;
import com.arcsoft.face.enums.*;
import org.apache.commons.lang3.StringUtils;
import javax.imageio.ImageIO;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.DataBufferByte;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* 人脸识别工具类
* @author zys
*/
public class ArcFaceHelper {
private static final String APP_ID = "52XE2dQBtdmMsfDMvyKmPCD1nGBSGQWQGUyJh5z9JhND";
/**
* x64
*/
private static final String WIN64_SDK_KEY = "GggpcEphVxXLXcpEZz6tdC19o3QhbuktDm3YTUhUGr7J";
/**
* linux_64
*/
private static final String LINUX64_SDK_KEY = "GggpcEphVxXLXcpEZz6tdC19evqXbbhMyYt71DGLwnCp";
private static FaceEngine faceEngine = null;
public static final float STANDARD_SCORE = 0.85F;
static {
try{
String os = System.getProperty("os.name");
if(StringUtils.startsWith(os.toLowerCase(), "win")){
faceEngine = new FaceEngine("D:\\arcsoft_lib_64");
//激活引擎
faceEngine.activeOnline(APP_ID, WIN64_SDK_KEY);
} else {
faceEngine = new FaceEngine("/data/arcsoft_lib_64");
//激活引擎
faceEngine.activeOnline(APP_ID, LINUX64_SDK_KEY);
}
}catch (Throwable e){
System.out.println("加载人脸识别引擎异常:" + e.getMessage());
}
}
public static FaceEngine getFaceEngine() {
return faceEngine;
}
public FaceResult getFaceFeatures(String imgSrc) {
if(imgSrc.contains("http")){
return getFaceFeatures(getNetUrlHttp(imgSrc));
}else{
return getFaceFeatures(new File(imgSrc));
}
}
public static FaceResult getFaceFeatures(File file) {
ImageInfo imageInfo = getRGBData(file);
if (imageInfo == null){
return null;
}
EngineConfiguration engineConfiguration = EngineConfiguration.builder().functionConfiguration(
FunctionConfiguration.builder()
.supportFaceDetect(true)
.supportAge(true)
.supportFace3dAngle(true)
.supportFaceDetect(true)
.supportFaceRecognition(true)
.supportGender(true)
.build()).build();
//初始化引擎
faceEngine.init(engineConfiguration);
//人脸检测
List<FaceInfo> lstFaceInfo = new ArrayList<FaceInfo>();
faceEngine.detectFaces(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(),
ImageFormat.CP_PAF_BGR24, lstFaceInfo);
System.out.println("检测到人脸数:" + lstFaceInfo.size());
if (lstFaceInfo.size() == 0) {
return null;
// throw new NullPointerException("未检测到人脸");
}
FaceResult result = new FaceResult();
//提取人脸特征
FaceFeature faceFeature = new FaceFeature();
int code = faceEngine.extractFaceFeature(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(),
ImageFormat.CP_PAF_BGR24, lstFaceInfo.get(0), faceFeature);
System.out.println("提取特征结果码:" + code);
result.setFeatures(faceFeature.getFeatureData());
//人脸信息检测
int processCode = faceEngine.process(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(),
ImageFormat.CP_PAF_BGR24, lstFaceInfo,
FunctionConfiguration.builder().supportAge(true).supportFace3dAngle(true).supportGender(true).build());
System.out.println("人脸信息检测码:" + processCode);
if(code != 0 || processCode != 0){
return null;
// throw new IllegalArgumentException("提取特征失败");
}
//性别提取
List<GenderInfo> genderInfoList = new ArrayList<GenderInfo>();
int genderCode = faceEngine.getGender(genderInfoList);
//0:MALE;1:FEMALE;-1:UNKNOWN
result.setSex(genderInfoList.get(0).getGender());
System.out.println("性别:" + genderInfoList.get(0).getGender() + ",性别提取码:" + genderCode);
//年龄提取
List<AgeInfo> ageInfoList = new ArrayList<AgeInfo>();
int ageCode = faceEngine.getAge(ageInfoList);
result.setAge(ageInfoList.get(0).getAge());
System.out.println("年龄:" + ageInfoList.get(0).getAge() + ",年龄提取码:" + ageCode);
//3D信息提取
List<Face3DAngle> face3DAngleList = new ArrayList<Face3DAngle>();
int face3dCode = faceEngine.getFace3DAngle(face3DAngleList);
System.out.println("3D信息" + face3DAngleList + "3D信息提取码" + face3dCode);
unInintEngine();
return result;
}
public static void unInintEngine() {
int code = faceEngine.unInit();
System.out.println("销毁引擎:" + code);
}
public static ImageInfo getRGBData(File file) {
if (file == null){
return null;
}
ImageInfo imageInfo;
try {
//将图片文件加载到内存缓冲区
BufferedImage image = ImageIO.read(file);
imageInfo = bufferedImage2ImageInfo(image);
} catch (IOException e) {
e.printStackTrace();
return null;
}
return imageInfo;
}
private static ImageInfo bufferedImage2ImageInfo(BufferedImage image) {
ImageInfo imageInfo = new ImageInfo();
int width = image.getWidth();
int height = image.getHeight();
// 使图片居中
width = width & (~3);
height = height & (~3);
imageInfo.setWidth(width);
imageInfo.setHeight(height);
//根据原图片信息新建一个图片缓冲区
BufferedImage resultImage = new BufferedImage(width, height, image.getType());
//得到原图的rgb像素矩阵
int[] rgb = image.getRGB(0, 0, width, height, null, 0, width);
//将像素矩阵 绘制到新的图片缓冲区中
resultImage.setRGB(0, 0, width, height, rgb, 0, width);
//进行数据格式化为可用数据
BufferedImage dstImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
try {
if (resultImage.getType() != BufferedImage.TYPE_3BYTE_BGR) {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
ColorConvertOp colorConvertOp = new ColorConvertOp(cs, dstImage.createGraphics().getRenderingHints());
colorConvertOp.filter(resultImage, dstImage);
} else {
dstImage = resultImage;
}
} catch (Exception e) {
// TODO: handle exception
System.err.println(e.toString());
}
//获取rgb数据
imageInfo.setRgbData(((DataBufferByte) (dstImage.getRaster().getDataBuffer())).getData());
return imageInfo;
}
private static File getNetUrlHttp(String path){
//对本地文件命名path是http的完整路径主要得到资源的名字
String newUrl = path;
newUrl = newUrl.split("[?]")[0];
String[] bb = newUrl.split("/");
//得到最后一个分隔符后的名字
String fileName = bb[bb.length - 1];
//保存到本地的路径
String filePath;
String os = System.getProperty("os.name");
if(StringUtils.startsWith(os.toLowerCase(), "win")){
filePath = "D:\\images\\"+fileName;
} else {
filePath = "/data/real_name/faceDetection/"+fileName;
}
File file = null;
URL urlfile;
InputStream inputStream = null;
OutputStream outputStream = null;
try{
//判断文件的父级目录是否存在不存在则创建
file = new File(filePath);
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
try{
//创建文件
file.createNewFile();
}catch (Exception e){
e.printStackTrace();
}
//下载
urlfile = new URL(newUrl);
inputStream = urlfile.openStream();
outputStream = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead=inputStream.read(buffer,0,8192))!=-1) {
outputStream.write(buffer, 0, bytesRead);
}
}catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (null != outputStream) {
outputStream.close();
}
if (null != inputStream) {
inputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return file;
}
}

View File

@ -0,0 +1,33 @@
package com.bonus.common.core.utils.face;
public class FaceResult {
private Integer age;
private Integer sex;
private byte[] features;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public byte[] getFeatures() {
return features;
}
public void setFeatures(byte[] features) {
this.features = features;
}
}

View File

@ -0,0 +1,33 @@
package com.bonus.common.core.utils.face;
public class ImageInfo {
private byte[] rgbData;
private int width;
private int height;
public byte[] getRgbData() {
return rgbData;
}
public void setRgbData(byte[] rgbData) {
this.rgbData = rgbData;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}

View File

@ -0,0 +1,186 @@
package com.bonus.common.core.utils.json;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import java.util.List;
/**
* @author fly
* @version 1
* json与jsonArray所有自定义bean嵌套的相关操作
* 将fast json 简单的封装和添加注释而成
* <dependency>
* <groupId>com.alibaba</groupId>
* <artifactId>fastjson</artifactId>
* <version>1.2.47</version>
* </dependency>
*修改时间:2021-09-30
*/
public class FastJsonHelper {
/**
* JSONArray : 相当于 List<Object>
* JSONObject: 相当于 Map<String,Object>
* public static final Object parse(String text); // 把JSON文本parse为JSONObject或者JSONArray
* public static final JSONObject parseObject(String text); // 把JSON文本parse成JSONObject
* public static final <T> T parseObject(String text, Class<T> clazz); // 把JSON文本parse为JavaBean
* public static final JSONArray parseArray(String text); // 把JSON文本parse成JSONArray
* public static final <T> List< > parseArray(String text, Class<T> clazz); //把JSON文本parse成JavaBean集合
* public static final String toJSONString(Object object); // 将JavaBean序列化为JSON文本 || JSONObject转成JSON文本
* public static final String toJSONString(Object object, boolean prettyFormat); // 将JavaBean序列化为带格式的JSON文本
* public static final Object toJSON(Object javaObject); //将JavaBean转换为JSONObject或者JSONArray
*/
/**
* 将任意bean转换成json字符串
* fast json
* @param bean
* @param <T>
* @return
*/
public static <T> String beanToJsonStr(T bean) {
String jsonStr = JSON.toJSONString(bean);
return jsonStr;
}
/**
* 把一个json字符串转换成bean对象
* fast json
* @param str
* @param <T>
* @return
*/
public static <T> T jsonStrToBean(String str, Class<T> clazz) {
T bean = JSON.parseObject(str, clazz);
return bean;
}
/**
* 把一个jsonObj转换成bean对象
* fast json
* @param jsonObj
* @param <T>
* @return
*/
public static <T> T jsonObjToBean(JSONObject jsonObj, Class<T> clazz) {
String s = jsonObj.toJSONString();
T bean = JSON.parseObject(s, clazz);
return bean;
}
/**
* 把一个bean对象转换成jsonObj
* fast json
* @param bean
* @param <T>
* @return
*/
public static <T> JSONObject beanToJsonObj(T bean) {
Object o = JSON.toJSON(bean);
return (JSONObject) o;
}
/**
* 把一个jsonStr转换成jsonObj
* fast json
* @param str
* @return
*/
public static JSONObject jsonStrToJsonObj(String str) {
Object o = JSON.parseObject(str);
return (JSONObject) o;
}
/**
* 把一个jsonObj转换成jsonStr
* fast json
* @param jsonObj
* @return
*/
public static String jsonObjToJsonStr(JSONObject jsonObj) {
String s = jsonObj.toJSONString();
return s;
}
/**
* 把一个beanList对象转换成jsonArrStr
* fast json
* @param beanList
* @param <T>
* @return
*/
public static <T> String beanListToJsonArrStr(List<T> beanList) {
JSONArray o = (JSONArray)JSON.toJSON(beanList);
String s = JSON.toJSONString(o);
return s;
}
/**
* 把一个jsonArrStr转换成beanList对象
* fast json
* @param jsonArrStr
* @param <T>
* @return
*/
public static <T> List<T> jsonArrStrToBeanList(String jsonArrStr, Class<T> clazz) {
List<T> ts = JSON.parseArray(jsonArrStr, clazz);
return ts;
}
/**
* 把一个JsonArr转换成JsonArrStr
* fast json
* @param jsonArr
* @return
*/
public static String jsonArrToJsonArrStr(JSONArray jsonArr) {
String s = JSON.toJSONString(jsonArr);
return s;
}
/**
* 把一个JsonArrStr文本转换成JsonArr
* fast json
* @param jsonArrStr
* @return
*/
public static JSONArray jsonArrStrToJsonArr(String jsonArrStr) {
Object o = JSON.parse(jsonArrStr);
return (JSONArray) o;
}
/**
* 把一个JsonArr转换成beanList
* fast json
* @param jsonArr
* @return
*/
public static <T> List<T> jsonArrToBeanList(JSONArray jsonArr, Class<T> clazz) {
String s = JSON.toJSONString(jsonArr);
List<T> ts = JSON.parseArray(s, clazz);
return ts;
}
/**
* 把一个beanList文本转换成JsonArr
* fast json
* @param beanList
* @return
*/
public static <T> JSONArray beanListToJsonArr(List<T> beanList) {
Object o = JSON.toJSON(beanList);
return (JSONArray) o;
}
}

View File

@ -3,6 +3,7 @@ import com.bonus.bmw.domain.vo.BmWorkerContract;
import com.bonus.bmw.domain.vo.BmWorkerWageCard;
import com.bonus.bmw.service.impl.BmWorkerContractServiceImpl;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.utils.json.FastJsonHelper;
import com.bonus.common.core.web.controller.BaseController;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.core.web.page.TableDataInfo;
@ -17,6 +18,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
@ -101,8 +103,11 @@ public class BmWorkerContractController extends BaseController {
@RequiresPermissionsOrInnerAuth(innerAuth = @InnerAuth)
@PostMapping("/edit")
@SysLog(title = "合同管理", businessType = OperaType.UPDATE, logType = 0, module = "施工人员->红绿灯管理->合同管理", details = "修改合同")
public AjaxResult edit(@Validated @RequestBody BmWorkerContract o) {
public AjaxResult edit(@RequestParam(value = "files") MultipartFile[] files,@RequestParam(value = "fileMsg") String fileMsg, @RequestParam(value = "params")String params) {
try {
System.out.println("fileMsg:"+fileMsg);
System.out.println(files.length);
BmWorkerContract o = FastJsonHelper.jsonStrToBean(params, BmWorkerContract.class);
return toAjax(service.updateByPrimaryKey(o));
} catch (Exception e) {
logger.error(e.toString(), e);

View File

@ -5,6 +5,8 @@ import com.bonus.bmw.domain.vo.BmWorkerWageCard;
import com.bonus.bmw.domain.vo.PmWorker;
import com.bonus.bmw.service.PmWorkerService;
import com.bonus.bmw.service.impl.PmWorkerServiceImpl;
import com.bonus.common.core.utils.face.ArcFaceHelper;
import com.bonus.common.core.utils.face.FaceResult;
import com.bonus.common.core.web.controller.BaseController;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.core.web.page.TableDataInfo;
@ -16,7 +18,11 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
@ -108,6 +114,42 @@ public class PmWorkerController extends BaseController {
return error("系统异常,请联系管理员");
}
/**
* 人脸照片合格检测
* @param file
* @return
*/
@RequiresPermissionsOrInnerAuth(innerAuth = @InnerAuth)
@PostMapping("/faceDetection")
@SysLog(title = "人脸照片合格检测", businessType = OperaType.UPDATE, logType = 0, module = "施工人员->出入场管理->人员入场管理", details = "人脸照片合格检测")
public AjaxResult faceDetection(@RequestParam(value = "file") MultipartFile file) {
if (file == null || file.isEmpty()) {
return AjaxResult.error("文件为空:" );
}
// 创建临时文件
File tempFile = null;
try {
// 获取文件后缀
String originalFilename = file.getOriginalFilename();
String suffix = "";
if (originalFilename != null && originalFilename.contains(".")) {
suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
}
// 创建临时文件
tempFile = Files.createTempFile("temp-image-", suffix).toFile();
tempFile.deleteOnExit(); // JVM退出时自动删除
// MultipartFile 写入临时文件
file.transferTo(tempFile);
ArcFaceHelper arcFaceHelper = new ArcFaceHelper();
// 调用原方法传入临时文件的路径
FaceResult faceFeatures = arcFaceHelper.getFaceFeatures(tempFile.getAbsolutePath());
return AjaxResult.success(faceFeatures);
} catch (IOException e) {
// 处理异常如磁盘满权限不足等
e.printStackTrace();
return AjaxResult.error("人脸检测失败:"+e.getMessage());
}
}
}