故事项新建调整,上传图像增加缩略图
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
package com.timeline.file.controller;
|
||||
|
||||
import com.timeline.file.entity.ImageInfo;
|
||||
import com.timeline.file.service.FileService;
|
||||
import com.timeline.file.vo.ImageInfoVo;
|
||||
import com.timeline.common.response.ResponseEntity;
|
||||
@@ -50,18 +49,22 @@ public class FileController {
|
||||
}
|
||||
@PostMapping("/upload-image")
|
||||
public ResponseEntity<String> uploadCover(@RequestPart("image") MultipartFile image) throws Throwable {
|
||||
String objectKey = fileService.uploadCover(image);
|
||||
String objectKey = fileService.uploadImage(image);
|
||||
return ResponseEntity.success(objectKey);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/image/{coverInstanceId}", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
|
||||
public void downloadCover(@PathVariable String coverInstanceId, HttpServletResponse response) throws Throwable {
|
||||
log.info("downloadCover");
|
||||
InputStream inputStream = fileService.downloadCover(coverInstanceId);
|
||||
@RequestMapping(value = "/image/{instanceId}", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
|
||||
public void fetchImage(@PathVariable String instanceId, HttpServletResponse response) throws Throwable {
|
||||
InputStream inputStream = fileService.fetchImage(instanceId);
|
||||
response.setContentType("image/jpeg");
|
||||
IOUtils.copy(inputStream, response.getOutputStream());
|
||||
}
|
||||
@RequestMapping(value = "/image-low-res/{instanceId}", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
|
||||
public void fetchImageLowRes(@PathVariable String instanceId, HttpServletResponse response) throws Throwable {
|
||||
InputStream inputStream = fileService.fetchImageLowRes(instanceId);
|
||||
response.setContentType("image/jpeg");
|
||||
IOUtils.copy(inputStream, response.getOutputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图片后绑定到某个 StoryItem
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,10 @@ public interface FileService {
|
||||
List<String> getStoryItemImages(String storyItemId);
|
||||
void removeImageFromStoryItem(String imageInstanceId, String storyItemId);
|
||||
ArrayList<String> getAllImageUrls(List<String> images) throws Throwable;
|
||||
String uploadCover(MultipartFile cover) throws Throwable;
|
||||
InputStream downloadCover(String coverKey) throws Throwable;
|
||||
String uploadImage(MultipartFile cover) throws Throwable;
|
||||
InputStream fetchImage(String coverKey) throws Throwable;
|
||||
|
||||
InputStream fetchImageLowRes(String instanceId) throws Throwable;
|
||||
|
||||
Map getImagesListByOwnerId(ImageInfoVo imageInfoVo);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.timeline.file.service.impl;
|
||||
|
||||
import com.timeline.common.constants.CommonConstants;
|
||||
import com.timeline.common.exception.CustomException;
|
||||
import com.timeline.common.response.ResponseEnum;
|
||||
import com.timeline.common.utils.CommonUtils;
|
||||
import com.timeline.common.utils.PageUtils;
|
||||
import com.timeline.file.config.MinioConfig;
|
||||
@@ -17,10 +18,13 @@ import io.minio.*;
|
||||
import io.minio.errors.MinioException;
|
||||
import io.minio.http.Method;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.coobird.thumbnailator.Thumbnails;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
@@ -110,10 +114,17 @@ public class FileServiceImpl implements FileService {
|
||||
|
||||
} else {
|
||||
// 不存在其他image_info使用则删除 MinIO 中的对象
|
||||
log.info("删除 MinIO 中的对象:{}", imageInfo.getObjectKey());
|
||||
minioClient.removeObject(RemoveObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.object(imageInfo.getObjectKey())
|
||||
.build());
|
||||
// 删除低分辨率图像
|
||||
log.info("删除 MinIO 中的低分辨率对象:{}", CommonConstants.LOW_RESOLUTION_PREFIX + imageInfo.getObjectKey());
|
||||
minioClient.removeObject(RemoveObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.object(CommonConstants.LOW_RESOLUTION_PREFIX + imageInfo.getObjectKey())
|
||||
.build());
|
||||
}
|
||||
// 删除file_hash
|
||||
fileHashMapper.deleteFileHash(instanceId);
|
||||
@@ -165,10 +176,11 @@ public class FileServiceImpl implements FileService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadCover(MultipartFile image) throws Throwable {
|
||||
public String uploadImage(MultipartFile image) throws Throwable {
|
||||
String suffix = Objects.requireNonNull(image.getOriginalFilename()).substring(image.getOriginalFilename().lastIndexOf("."));
|
||||
String hash = CommonUtils.calculateFileHash(image);
|
||||
String objectKey = hash + suffix;
|
||||
String lowResolutionObjectKey = CommonConstants.LOW_RESOLUTION_PREFIX + hash + suffix;
|
||||
log.info("上传图片的ObjectKey值为:{}", objectKey);
|
||||
List<FileHash> hashByFileHash = fileHashMapper.getFileHashByFileHash(hash);
|
||||
// 2. 保存元数据到 MySQL
|
||||
@@ -190,6 +202,26 @@ public class FileServiceImpl implements FileService {
|
||||
.stream(image.getInputStream(), image.getSize(), -1)
|
||||
.contentType(image.getContentType())
|
||||
.build());
|
||||
// 生成并上传低分辨率版本
|
||||
try (InputStream inputStream = image.getInputStream()) {
|
||||
ByteArrayOutputStream lowResOutputStream = new ByteArrayOutputStream();
|
||||
Thumbnails.of(inputStream)
|
||||
.size(300, 300) // 设置低分辨率版本大小
|
||||
.outputQuality(0.7) // 设置压缩质量
|
||||
.toOutputStream(lowResOutputStream);
|
||||
|
||||
ByteArrayInputStream lowResInputStream = new ByteArrayInputStream(lowResOutputStream.toByteArray());
|
||||
minioClient.putObject(PutObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.object(lowResolutionObjectKey)
|
||||
.stream(lowResInputStream, lowResInputStream.available(), -1)
|
||||
.contentType(image.getContentType())
|
||||
.build());
|
||||
|
||||
log.info("低分辨率版本已生成并上传: {}", lowResolutionObjectKey);
|
||||
} catch (Exception e) {
|
||||
log.error("生成低分辨率版本失败", e);
|
||||
}
|
||||
}
|
||||
fileHashMapper.insertFileHash(new FileHash(imageInfo.getInstanceId(), hash));
|
||||
imageInfoMapper.insert(imageInfo);
|
||||
@@ -198,15 +230,40 @@ public class FileServiceImpl implements FileService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream downloadCover(String coverInstanceId) throws Throwable {
|
||||
log.info("获取");
|
||||
String objectKey = imageInfoMapper.selectObjectKeyById(coverInstanceId);
|
||||
public InputStream fetchImage(String instanceId) throws Throwable {
|
||||
String objectKey = imageInfoMapper.selectObjectKeyById(instanceId);
|
||||
log.info("获取图像{}, objectKey:{}", instanceId, objectKey);
|
||||
if (objectKey == null) {
|
||||
throw new CustomException(ResponseEnum.NOT_FOUND_ERROR);
|
||||
}
|
||||
return minioClient.getObject(GetObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.object(objectKey)
|
||||
.build());
|
||||
}
|
||||
@Override
|
||||
public InputStream fetchImageLowRes(String instanceId) throws Throwable {
|
||||
String objectKey = imageInfoMapper.selectObjectKeyById(instanceId);
|
||||
log.info("获取图像低分辨率版本{}, objectKey:{}", instanceId, objectKey);
|
||||
if (objectKey == null) {
|
||||
throw new CustomException(ResponseEnum.NOT_FOUND_ERROR);
|
||||
}
|
||||
String lowResObjectKey = CommonConstants.LOW_RESOLUTION_PREFIX + objectKey;
|
||||
|
||||
// 优先返回低分辨率版本,如果不存在则返回原图
|
||||
if (doesObjectExist(lowResObjectKey)) {
|
||||
return minioClient.getObject(GetObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.object(lowResObjectKey)
|
||||
.build());
|
||||
} else {
|
||||
log.warn("低分辨率版本不存在,返回原图: {}", objectKey);
|
||||
return minioClient.getObject(GetObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.object(objectKey)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Map getImagesListByOwnerId(ImageInfoVo imageInfoVo) {
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
@@ -215,4 +272,24 @@ public class FileServiceImpl implements FileService {
|
||||
map, "list");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查对象是否存在
|
||||
* @param objectKey 对象键
|
||||
* @return true表示存在,false表示不存在
|
||||
*/
|
||||
private boolean doesObjectExist(String objectKey) {
|
||||
try {
|
||||
minioClient.statObject(StatObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.object(objectKey)
|
||||
.build());
|
||||
return true;
|
||||
} catch (MinioException e) {
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
log.error("检查对象是否存在时出错: {}", objectKey, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user