This commit is contained in:
2026-10-24 13:31:43 +08:00
parent ed94879b36
commit 3fef36a721
114 changed files with 5321 additions and 1463 deletions
@@ -30,9 +30,17 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
@@ -46,6 +54,11 @@ import java.util.List;
@RestController
@RequestMapping("/api/file")
public class FileController extends BaseController {
private static final int FACE_MIN_WIDTH = 480;
private static final int FACE_MIN_HEIGHT = 640;
private static final int FACE_MAX_WIDTH = 1080;
private static final int FACE_MAX_HEIGHT = 1920;
@Resource
private ConfigProperties config;
@Resource
@@ -172,6 +185,40 @@ public class FileController extends BaseController {
}
}
@PreAuthorize("hasAuthority('sys:file:upload')")
@OperationLog
@ApiOperation("上传人脸图片并返回base64")
@PostMapping("/upload/face")
public ApiResult<String> uploadFace(@RequestParam MultipartFile file) {
try {
if (file == null || file.isEmpty()) {
return fail("上传失败,文件为空", null);
}
byte[] originalBytes = file.getBytes();
BufferedImage image;
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(originalBytes)) {
image = ImageIO.read(inputStream);
}
if (image == null) {
return fail("上传失败,无法解析图片", null);
}
int width = image.getWidth();
int height = image.getHeight();
boolean inRange = width >= FACE_MIN_WIDTH && height >= FACE_MIN_HEIGHT
&& width <= FACE_MAX_WIDTH && height <= FACE_MAX_HEIGHT;
boolean isJpeg = isJpegImage(file.getContentType(), file.getOriginalFilename());
if (inRange && isJpeg) {
return success(Base64.getEncoder().encodeToString(originalBytes));
}
BufferedImage converted = resizeToRange(toRgbImage(image), width, height);
byte[] jpegBytes = toJpegBytes(converted);
return success(Base64.getEncoder().encodeToString(jpegBytes));
} catch (Exception e) {
e.printStackTrace();
return fail("上传失败", null).setError(e.toString());
}
}
@PreAuthorize("hasAuthority('sys:file:list')")
@OperationLog
@ApiOperation("根据id查询文件")
@@ -350,4 +397,61 @@ public class FileController extends BaseController {
return fail("修改失败");
}
private static boolean isJpegImage(String contentType, String fileName) {
if (contentType != null) {
String ct = contentType.toLowerCase();
if (ct.contains("jpeg") || ct.contains("jpg")) {
return true;
}
}
if (fileName != null) {
String lower = fileName.toLowerCase();
return lower.endsWith(".jpg") || lower.endsWith(".jpeg");
}
return false;
}
private static BufferedImage toRgbImage(BufferedImage source) {
if (source.getType() == BufferedImage.TYPE_INT_RGB) {
return source;
}
BufferedImage rgb = new BufferedImage(source.getWidth(), source.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = rgb.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, rgb.getWidth(), rgb.getHeight());
g2d.drawImage(source, 0, 0, null);
g2d.dispose();
return rgb;
}
private static BufferedImage resizeToRange(BufferedImage image, int width, int height) {
double scale = 1.0;
if (width < FACE_MIN_WIDTH || height < FACE_MIN_HEIGHT) {
scale = Math.max(FACE_MIN_WIDTH / (double) width, FACE_MIN_HEIGHT / (double) height);
} else if (width > FACE_MAX_WIDTH || height > FACE_MAX_HEIGHT) {
scale = Math.min(FACE_MAX_WIDTH / (double) width, FACE_MAX_HEIGHT / (double) height);
} else {
return image;
}
int targetWidth = Math.max(1, (int) Math.round(width * scale));
int targetHeight = Math.max(1, (int) Math.round(height * scale));
BufferedImage resized = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = resized.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.drawImage(image, 0, 0, targetWidth, targetHeight, null);
g2d.dispose();
return resized;
}
private static byte[] toJpegBytes(BufferedImage image) throws Exception {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
if (!ImageIO.write(image, "jpg", outputStream)) {
throw new IllegalStateException("jpeg encode fail");
}
return outputStream.toByteArray();
}
}
}