FileUploadController.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. package com.izouma.nineth.web;
  2. import com.izouma.nineth.domain.FileObject;
  3. import com.izouma.nineth.exception.BusinessException;
  4. import com.izouma.nineth.service.storage.StorageService;
  5. import com.izouma.nineth.utils.DateTimeUtils;
  6. import com.izouma.nineth.utils.ImageUtils;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.apache.commons.io.FileUtils;
  9. import org.apache.commons.io.FilenameUtils;
  10. import org.apache.commons.lang3.ArrayUtils;
  11. import org.apache.commons.lang3.RandomStringUtils;
  12. import org.apache.commons.lang3.StringUtils;
  13. import org.apache.poi.util.TempFile;
  14. import org.bytedeco.javacv.FFmpegFrameGrabber;
  15. import org.bytedeco.javacv.Frame;
  16. import org.bytedeco.javacv.Java2DFrameConverter;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.web.bind.annotation.PostMapping;
  19. import org.springframework.web.bind.annotation.RequestMapping;
  20. import org.springframework.web.bind.annotation.RequestParam;
  21. import org.springframework.web.bind.annotation.RestController;
  22. import org.springframework.web.multipart.MultipartFile;
  23. import javax.imageio.ImageIO;
  24. import java.awt.image.BufferedImage;
  25. import java.io.*;
  26. import java.net.URLConnection;
  27. import java.text.SimpleDateFormat;
  28. import java.time.LocalDate;
  29. import java.time.LocalDateTime;
  30. import java.util.*;
  31. import java.util.regex.Pattern;
  32. @RestController
  33. @RequestMapping("/upload")
  34. @Slf4j
  35. public class FileUploadController {
  36. @Autowired
  37. private StorageService storageService;
  38. @PostMapping("/file")
  39. public String uploadFile(@RequestParam("file") MultipartFile file,
  40. @RequestParam(value = "path", required = false) String path,
  41. @RequestParam(value = "compress", defaultValue = "false") boolean compress,
  42. @RequestParam(value = "width", required = false) Integer width,
  43. @RequestParam(value = "height", required = false) Integer height) throws IOException {
  44. if ("aarch64".equals(System.getProperty("os.arch"))) compress = false;
  45. String ext = Optional.ofNullable(FilenameUtils.getExtension(file.getOriginalFilename())).orElse("")
  46. .toLowerCase().replace("jpeg", "jpg");
  47. if (path == null) {
  48. String basePath = Optional.ofNullable(file.getContentType()).orElse("application").split("/")[0];
  49. path = basePath + "/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date())
  50. + RandomStringUtils.randomAlphabetic(8)
  51. + "." + ext;
  52. }
  53. if (Pattern.matches("(jpg|png)", ext) && (compress || width != null || height != null)) {
  54. if (width == null && height == null) {
  55. width = Integer.MAX_VALUE;
  56. height = Integer.MAX_VALUE;
  57. } else if (height == null) {
  58. height = Integer.MAX_VALUE;
  59. } else if (width == null) {
  60. width = Integer.MAX_VALUE;
  61. }
  62. BufferedImage img = null;
  63. if ("jpg".equals(ext)) {
  64. img = ImageUtils.resizeJpg(file.getInputStream(), width, height, compress);
  65. } else if ("png".equals(ext)) {
  66. img = ImageUtils.resizePng(file.getInputStream(), width, height, compress);
  67. }
  68. Objects.requireNonNull(img, "图片压缩失败");
  69. ByteArrayOutputStream os = new ByteArrayOutputStream();
  70. ImageIO.write(img, ext, os);
  71. InputStream is = new ByteArrayInputStream(os.toByteArray());
  72. return storageService.uploadFromInputStream(is, path);
  73. }
  74. return storageService.uploadFromInputStream(file.getInputStream(), path);
  75. }
  76. @PostMapping("/base64")
  77. public String uploadImage(@RequestParam("base64") String base64,
  78. @RequestParam(value = "path", required = false) String path) {
  79. base64 = base64.substring(base64.indexOf(',') + 1);
  80. Base64.Decoder decoder = Base64.getDecoder();
  81. if (path == null) {
  82. String ext = ".jpg";
  83. try {
  84. InputStream is = new ByteArrayInputStream(decoder.decode(base64.getBytes()));
  85. String type = URLConnection.guessContentTypeFromStream(is);
  86. ext = type.replace("image/", ".").replace("jpeg", "jpg");
  87. } catch (Exception ignored) {
  88. }
  89. path = "image/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date())
  90. + RandomStringUtils.randomAlphabetic(8) + ext;
  91. }
  92. InputStream is;
  93. try {
  94. is = new ByteArrayInputStream(decoder.decode(base64.getBytes()));
  95. } catch (Exception e) {
  96. log.error("上传失败", e);
  97. throw new BusinessException("上传失败", e.getMessage());
  98. }
  99. return storageService.uploadFromInputStream(is, path);
  100. }
  101. @PostMapping("/fileObject")
  102. public FileObject uploadFileObject(@RequestParam("file") MultipartFile file,
  103. @RequestParam(value = "compress", defaultValue = "false") boolean compress,
  104. @RequestParam(value = "width", required = false) Integer width,
  105. @RequestParam(value = "height", required = false) Integer height) throws IOException {
  106. if ("aarch64".equals(System.getProperty("os.arch"))) compress = false;
  107. String ext = Optional.ofNullable(FilenameUtils.getExtension(file.getOriginalFilename())).orElse("")
  108. .toLowerCase().replace("jpeg", "jpg");
  109. String[] extList = new String[]{"jpg", "jpeg", "png", "gif", "mp4"};
  110. if (!ArrayUtils.contains(extList, ext.toLowerCase())) {
  111. throw new BusinessException("仅支持" + StringUtils.join(extList, "、") + "格式");
  112. }
  113. File tmpFile = File.createTempFile("upload_", "." + ext);
  114. FileUtils.copyToFile(file.getInputStream(), tmpFile);
  115. String path = "nft/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date())
  116. + RandomStringUtils.randomAlphabetic(8)
  117. + "." + ext;
  118. String url;
  119. if (Pattern.matches("(jpg|png)", ext) && (compress || width != null || height != null)) {
  120. if (width == null && height == null) {
  121. width = Integer.MAX_VALUE;
  122. height = Integer.MAX_VALUE;
  123. } else if (height == null) {
  124. height = Integer.MAX_VALUE;
  125. } else if (width == null) {
  126. width = Integer.MAX_VALUE;
  127. }
  128. BufferedImage img;
  129. if ("jpg".equals(ext)) {
  130. img = ImageUtils.resizeJpg(new FileInputStream(tmpFile), width, height, compress);
  131. } else {
  132. img = ImageUtils.resizePng(new FileInputStream(tmpFile), width, height, compress);
  133. }
  134. ByteArrayOutputStream os = new ByteArrayOutputStream();
  135. ImageIO.write(img, ext, os);
  136. InputStream is = new ByteArrayInputStream(os.toByteArray());
  137. url = storageService.uploadFromInputStream(is, path);
  138. } else {
  139. url = storageService.uploadFromInputStream(new FileInputStream(tmpFile), path);
  140. }
  141. String thumbUrl = null;
  142. if ("mp4".equalsIgnoreCase(ext)) {
  143. String thumbPath = "thumb_image/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date())
  144. + RandomStringUtils.randomAlphabetic(8) + ".jpg";
  145. FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(tmpFile);
  146. Java2DFrameConverter frameConverter = new Java2DFrameConverter();
  147. try {
  148. frameGrabber.start();
  149. Frame frame = null;
  150. while (frame == null) {
  151. frame = frameGrabber.grabKeyFrame();
  152. }
  153. Objects.requireNonNull(frame, "获取视频缩略图失败");
  154. BufferedImage thumbBi = frameConverter.convert(frame);
  155. BufferedImage thumbResized = ImageUtils.resizeJpg(thumbBi, 1000, 1000, false);
  156. ByteArrayOutputStream os = new ByteArrayOutputStream();
  157. ImageIO.write(thumbResized, "jpg", os);
  158. InputStream is = new ByteArrayInputStream(os.toByteArray());
  159. thumbUrl = storageService.uploadFromInputStream(is, thumbPath);
  160. } catch (Exception e) {
  161. e.printStackTrace();
  162. } finally {
  163. frameGrabber.stop();
  164. }
  165. }
  166. return new FileObject(file.getOriginalFilename(), url, thumbUrl, file.getContentType());
  167. }
  168. @PostMapping("/3dModel")
  169. public FileObject upload3dModel(@RequestParam("file") MultipartFile file) throws IOException {
  170. if (!"zip".equalsIgnoreCase(FilenameUtils.getExtension(file.getOriginalFilename()))) {
  171. throw new BusinessException("只能上传zip");
  172. }
  173. File destDir = TempFile.createTempDirectory(RandomStringUtils.randomAlphabetic(20));
  174. com.izouma.nineth.utils.FileUtils.unzip(file.getInputStream(), destDir);
  175. File fbxFile = com.izouma.nineth.utils.FileUtils.findInDir(destDir, ".fbx");
  176. if (fbxFile == null) {
  177. throw new BusinessException("找不到fbx文件");
  178. }
  179. File fbxDir = fbxFile.getParentFile();
  180. String basePath = "fbx/"
  181. + new SimpleDateFormat("yyyy-MM_dd-HH").format(new Date()) + "/"
  182. + RandomStringUtils.randomAlphabetic(16);
  183. List<String> urls = new ArrayList<>();
  184. for (File listFile : fbxDir.listFiles()) {
  185. if (!listFile.isHidden() && !listFile.isDirectory()) {
  186. urls.add(storageService.uploadFromInputStream(new FileInputStream(listFile), basePath + "/" + listFile.getName()));
  187. }
  188. }
  189. String fbxUrl = urls.stream().filter(s -> s.toLowerCase().endsWith(".fbx")).findAny()
  190. .orElseThrow(new BusinessException("找不到fbx文件"));
  191. return new FileObject(fbxFile.getName(), fbxUrl, null, "fbx");
  192. }
  193. @PostMapping("/user")
  194. public String uploadFile(@RequestParam("file") MultipartFile file, @RequestParam String type,
  195. @RequestParam(defaultValue = "1000") int size) throws IOException {
  196. String ext = Optional.ofNullable(FilenameUtils.getExtension(file.getOriginalFilename())).orElse("")
  197. .toLowerCase().replace("jpeg", "jpg");
  198. String path = "user/" + type + "/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date())
  199. + RandomStringUtils.randomAlphabetic(8)
  200. + "." + ext;
  201. return uploadFile(file, path, true, size, size);
  202. }
  203. }