一般情况商品的图片都会有原图和缩略图,其他很多场景也会应用到,一个图片上传后,可能会保存不止一份文件,有的时候要保存它的缩略图,需要进行压缩处理,然后保存,也就是一个图片.最终保存了多个类似图片;
这里面有两个问题, 一 是如何做对应关系 二 是如何处理缩略图,压缩图片,使得保存的图片不模糊,不失比例

这里采用 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();
	}