package com.izouma.nineth.web; import com.izouma.nineth.domain.FileObject; import com.izouma.nineth.exception.BusinessException; import com.izouma.nineth.service.storage.StorageService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.Java2DFrameConverter; import org.pngquant.PngQuant; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.*; import java.net.URLConnection; import java.text.SimpleDateFormat; import java.util.Base64; import java.util.Date; import java.util.Objects; import java.util.Optional; import java.util.regex.Pattern; @RestController @RequestMapping("/upload") @Slf4j public class FileUploadController { @Autowired private StorageService storageService; @PostMapping("/file") public String uploadFile(@RequestParam("file") MultipartFile file, @RequestParam(value = "path", required = false) String path, @RequestParam(value = "compress", defaultValue = "false") boolean compress, @RequestParam(value = "width", required = false) Integer width, @RequestParam(value = "height", required = false) Integer height) throws IOException { if (width != null && height == null) { height = Integer.MAX_VALUE; } if (height != null && width == null) { width = Integer.MAX_VALUE; } String ext = Optional.ofNullable(FilenameUtils.getExtension(file.getOriginalFilename())).orElse("") .toLowerCase().replace("jpeg", "jpg"); if (Pattern.matches("(jpg|png)", ext)) { File tmpFile = null; try { tmpFile = File.createTempFile("upload", "." + ext); FileUtils.copyToFile(file.getInputStream(), tmpFile); } catch (IOException e) { e.printStackTrace(); throw new BusinessException("上传失败"); } PngQuant pngQuant = new PngQuant(); ImageIO.write(pngQuant.getRemapped(ImageIO.read(file.getInputStream())), "png", new File("/Users/drew/Downloads/111.png")); } if (path == null) { String basePath = "application"; try { basePath = file.getContentType().split("/")[0]; } catch (Exception ignored) { } path = basePath + "/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + RandomStringUtils.randomAlphabetic(8) + "." + FilenameUtils.getExtension(file.getOriginalFilename()); } InputStream is; try { is = file.getInputStream(); } catch (IOException e) { log.error("上传失败", e); throw new BusinessException("上传失败", e.getMessage()); } return storageService.uploadFromInputStream(is, path); } @PostMapping("/base64") public String uploadImage(@RequestParam("base64") String base64, @RequestParam(value = "path", required = false) String path) { base64 = base64.substring(base64.indexOf(',') + 1); Base64.Decoder decoder = Base64.getDecoder(); if (path == null) { String ext = ".jpg"; try { InputStream is = new ByteArrayInputStream(decoder.decode(base64.getBytes())); String type = URLConnection.guessContentTypeFromStream(is); ext = type.replace("image/", ".").replace("jpeg", "jpg"); } catch (Exception ignored) { } path = "image/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + RandomStringUtils.randomAlphabetic(8) + ext; } InputStream is; try { is = new ByteArrayInputStream(decoder.decode(base64.getBytes())); } catch (Exception e) { log.error("上传失败", e); throw new BusinessException("上传失败", e.getMessage()); } return storageService.uploadFromInputStream(is, path); } @PostMapping("/fileObject") public FileObject uploadFileObject(@RequestParam("file") MultipartFile file) throws IOException { String ext = Optional.ofNullable(FilenameUtils.getExtension(file.getOriginalFilename())).orElse(""); String[] extList = new String[]{"jpg", "jpeg", "png", "gif", "mp4"}; if (!ArrayUtils.contains(extList, ext.toLowerCase())) { throw new BusinessException("仅支持" + StringUtils.join(extList, "、") + "格式"); } File tmpFile = File.createTempFile("upload_", "." + ext); FileUtils.copyToFile(file.getInputStream(), tmpFile); String path = "nft/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + RandomStringUtils.randomAlphabetic(8) + "." + ext; String url = storageService.uploadFromInputStream(new FileInputStream(tmpFile), path); String thumbUrl = null; if ("mp4".equalsIgnoreCase(ext)) { FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(tmpFile); frameGrabber.start(); Java2DFrameConverter aa = new Java2DFrameConverter(); try { BufferedImage bi; Frame f = frameGrabber.grabKeyFrame(); bi = aa.convert(f); File thumbFile = null; while (bi != null) { thumbFile = File.createTempFile("video_thumb_", ".png"); PngQuant pngQuant = new PngQuant(); ImageIO.write(pngQuant.getRemapped(bi), "png", thumbFile); f = frameGrabber.grabKeyFrame(); bi = aa.convert(f); } Objects.requireNonNull(thumbFile); String thumbPath = "thumb_image/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + RandomStringUtils.randomAlphabetic(8) + ".png"; thumbUrl = storageService.uploadFromInputStream(new FileInputStream(thumbFile), thumbPath); } catch (Exception e) { e.printStackTrace(); } finally { frameGrabber.stop(); } } return new FileObject(file.getOriginalFilename(), url, thumbUrl, file.getContentType()); } }