图片上传、略缩图

service层

package com.example.common.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.entity.SysFile;
import com.example.common.mapper.SysFileMapper;
import com.example.common.service.SysFileService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

@Slf4j
@Service
@RequiredArgsConstructor
public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> implements SysFileService {

    /**
     * 图片压缩率,0.5代表50%,1代表原图不压缩
     */
    public static final double scale = 0.5;
    public static final String SUFFIX_THUMBNAIL = "-thumbnail";

    @Value("${file-path}")
    private String basePath;

    /**
     * 以fileId重命名文件, 并获得存储路径.
     * @param fileId
     * @param fileName
     * @return  ~/tmp/fileId.***
     */
    private String getPath(String fileId, String fileName) {
        /*
        * String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.
        * ①: %s: 转换符. 字符串类型.
        * ②: File.separator: 文件分隔符"\"(Window), "/"(Linux)
        * ③: StrUtil.addSuffixIfNot(basePath, File.separator): basePath如果不以"\"结尾, 在后面拼接上"\"
        * ④: public static final String DOT = "."
        * ⑤: FileUtil.extName(fileName): 获得fileName的后缀
        * */
        return String.format("%s%s%s%s", StrUtil.addSuffixIfNot(basePath, File.separator), fileId, StrUtil.DOT, FileUtil.extName(fileName));
    }

    /**
     * 以fileId重命名的文件的文件路径.
     * @param fileId
     * @param fileName
     * @return fileId.***
     */
    private String getFilePath(String fileId, String fileName) {
        return String.format("%s%s%s", fileId, StrUtil.DOT, FileUtil.extName(fileName));
    }

    /**
     * 略缩图的存储路径
     * @param fileId
     * @param fileName
     * @return
     */
    private String getThumbnailPath(String fileId, String fileName) {
        return String.format("%s%s%s%s", fileId, SUFFIX_THUMBNAIL, StrUtil.DOT, FileUtil.extName(fileName));
    }

    /**
     * 文件上传
     * @param file 文件
     * @return
     */
    @Override
    @SneakyThrows
    public SysFile upload(MultipartFile file) {
        /*
        * Content-Type: 在Http协议消息头中, 使用Content-Type来表示具体请求中的媒体类型信息.
        * 图片格式类型有: image/gif; image/jpeg; image/png
        * */
        // 判断是否是图片
        boolean isImage = StrUtil.startWith(file.getContentType(), "image");
        String fileId = IdWorker.getIdStr();
        /*
         * file.getOriginalFilename()得到的是上传时的文件名.
         * */
        String path = getPath(fileId, file.getOriginalFilename());
        log.info("上传文件:类型:[{}],大小:[{}],存储路径:[{}]", file.getContentType(), file.getSize(), path);
        /*
         * 将流的内容写入文件
         * ①: file.getInputStream(): 输入流
         * ②: path: 目标文件(String-->File)
         * */
        File fromFile = FileUtil.writeFromStream(file.getInputStream(), path);

        SysFile sysFile = new SysFile(file.getOriginalFilename(), file.getContentType(), file.getSize());
        sysFile.setId(fileId);
        sysFile.setPath(getFilePath(fileId, file.getOriginalFilename()));
        /*
         * 创建略缩图
         * */
        if (isImage) {
            try {
                Thumbnails.of(fromFile)
                        .scale(scale)
                        .toFile(FileUtil.file(getPath(fileId + SUFFIX_THUMBNAIL, file.getOriginalFilename())));
                sysFile.setThumbnailPath(getThumbnailPath(fileId, file.getOriginalFilename()));
            } catch (IOException e) {
                log.error("创建缩略图失败", e);
            }
        }
       /*
        * 把路径保存到数据库
        * */
        super.save(sysFile);
        return sysFile;
    }
    
}

配置文件application.yml

# 上传文件存放路径
file-path: ~/tmp/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值