一般情况商品的图片都会有原图和缩略图,其他很多场景也会应用到,一个图片上传后,可能会保存不止一份文件,有的时候要保存它的缩略图,需要进行压缩处理,然后保存,也就是一个图片.最终保存了多个类似图片;
这里面有两个问题, 一 是如何做对应关系 二 是如何处理缩略图,压缩图片,使得保存的图片不模糊,不失比例
这里采用 hutool 中的图片处理类,直接处理,此方法是按照等比缩放的;
主要代码如下:
/**
* @Description logo文件上传
* @Author FL
* @Date 17:58 2021/9/1
* @Param [file]
*/
@Override
@Transactional
public UploadFileVo uploadLogoFile(MultipartFile file) {
String userId = CurrentUserUtil.currentUserId();
String tenantId = CurrentUserUtil.currentTenantId();
if (file.isEmpty()) {
throw new MixException(BusinessErrorEnum.DATA_NOT_EXIST);
}
String originalFilename = file.getOriginalFilename();
int pos = originalFilename.lastIndexOf(".");
String fileName = originalFilename.substring(pos).toLowerCase();
long count = imgList.stream().filter(suffix -> fileName.indexOf(suffix) > 0).count();
if (count < 1L) {
throw new MixException(BusinessErrorEnum.IMAGE_TYPE_ERROR);
}
long fileSize = file.getSize();
log.info("图片大小:{}", fileSize);
if (fileSize > FIVE_M) {
throw new MixException(BusinessErrorEnum.FILE_IS_TOO_LARGE);
}
UpmsTenant upmsTenant = getById(tenantId);
if (null == upmsTenant) {
throw new MixException(BusinessErrorEnum.DATA_NOT_EXIST);
}
if (StrUtil.isBlank(upmsTenant.getFounderUserId()) || !upmsTenant.getFounderUserId().equals(userId)) {
throw new MixException(BusinessErrorEnum.ROLE_PERMISSION_DENIED);
}
// 文件过大压缩图片
String property = System.getProperty("user.dir");
String temPath = property + "/" + originalFilename;
log.info("临时路径:{}", temPath);
File imageFile = FileUtil.file(temPath);
MultipartFile multipartFile = null;
try {
if (fileSize > FIVE_M / 3) {
File temFile = new File(property + "/tem/" + originalFilename);
FileUtils.copyInputStreamToFile(file.getInputStream(), temFile);
ImageUtil.scale(temFile, imageFile, 0.5f);
multipartFile = FileCovertUtils.getMulFileByFile(imageFile);
log.info("压缩后图片大小:{}", multipartFile.getSize());
if (temFile.exists()) {
temFile.delete();
}
} else {
multipartFile = file;
}
} catch (IOException e) {
log.info("图片压缩异常:{}", e.getMessage());
throw new MixException(BusinessErrorEnum.BASE_SERVER_UNKNOWN);
}
Result<UploadFileVo> uploadFileVoResult = fssFeignClient.uploadFile(multipartFile,PIC_TYPE);
log.info("文件上传返回:{}", JSONUtil.toJsonStr(uploadFileVoResult));
if (imageFile.exists()) {
imageFile.delete();
}
if (!uploadFileVoResult.getCode().equals(BusinessErrorEnum.SUCCESS.getCode())) {
throw new MixException(uploadFileVoResult.getCode(), uploadFileVoResult.getMsg());
}
upmsTenant.setLogo(uploadFileVoResult.getData().getFileName());
updateById(upmsTenant);
return uploadFileVoResult.getData();
}
另附上, FileCovertUtils 的工具类内容
@Slf4j
public class FileCovertUtils {
public static void main(String[] args) {
try {
String picPath = "D:/originalfile/10001.png";
File f = new File(picPath);
MultipartFile file = getMulFileByFile(f);
log.info(file.getOriginalFilename());
} catch(Exception e) {
e.printStackTrace();
}
}
public static MultipartFile getMulFileByFile(File file) {
FileItem fileItem = createFileItem(file.getPath(),file.getName());
MultipartFile mfile = new CommonsMultipartFile(fileItem);
return mfile;
}
public static FileItem createFileItem(String filePath,String fileName){
String fieldName = "file";
FileItemFactory factory = new DiskFileItemFactory(16, null);
FileItem item = factory.createItem(fieldName, "text/plain", false,fileName);
File newfile = new File(filePath);
int bytesRead = 0;
byte[] buffer = new byte[8192];
try
{
FileInputStream fis = new FileInputStream(newfile);
OutputStream os = item.getOutputStream();
while ((bytesRead = fis.read(buffer, 0, 8192))!= -1)
{
os.write(buffer, 0, bytesRead);
}
os.close();
fis.close();
}
catch (IOException e)
{
log.info("图片压缩异常:{}",e.getMessage());
throw new MixException(BusinessErrorEnum.BASE_SERVER_UNKNOWN);
}
return item;
}
}
其中 重点代码是这里
File temFile = new File(property + "/tem/" + originalFilename);
FileUtils.copyInputStreamToFile(file.getInputStream(), temFile);
ImageUtil.scale(temFile, imageFile, 0.5f);
multipartFile = FileCovertUtils.getMulFileByFile(imageFile);
创建了一个临时空文件,然后将原有文件进行 0.5 缩放,然后写入之前的临时空文件中,这样就得到了一个缩略图;
不用hutool ,直接采用java 原生方式处理:
public byte[] scaleImage(MultipartFile file) throws IOException {
InputStream in = file.getInputStream();
String fileName = file.getOriginalFilename();
String formatName = fileName.substring(fileName.lastIndexOf(".") +1).toLowerCase();
// 获得原始图片
BufferedImage im = ImageIO.read(in);
// 设置缩略图参数
int width = (int) (Float.parseFloat(String.valueOf(im.getWidth())) * 0.5);
int height = (int) (Float.parseFloat(String.valueOf(im.getHeight())) * 0.5);
// 新生成结果图片
BufferedImage result = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
Image src = im.getScaledInstance(width, height, Image.SCALE_SMOOTH);
result.getGraphics().drawImage(src, 0, 0, null);
ByteArrayOutputStream bs = new ByteArrayOutputStream();
ImageOutputStream imOut = ImageIO.createImageOutputStream(bs);
ImageIO.write(result, formatName, imOut);
return bs.toByteArray();
}