七牛文件上传并将图片压缩加密base64

已上传图片为例,视频,文本等也可以用上传的方法,但是压缩只是针对图片的处理,可根据自己的业务逻辑去更改,我这里只写出了方法,具体对应的类自己去建

1.pom中引入包

        <!--thumbnailator 压缩工具-->
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.8</version>
        </dependency>

 2.controller的主要调用方法

public Result<Object> test(String accessToken, @RequestParam("file") MultipartFile file,HttpServletRequest request) throws IOException {
        String originName = file.getOriginalFilename(); //得到上传时的文件名
        //获取上传文件的后缀
        String imageSuffix = originName.substring(originName.lastIndexOf(".") + 1);
        //因jpg相对比较小,融云建议指上传jpg的
        if (!(imageSuffix.equalsIgnoreCase("jpg"))) {
            return new ResultUtil<Object>().setErrorMsg(300,"只允许传入jpg格式的图片");
        }
        String fileName = qiniuUtil.renamePic(originName);//重新命名上传七牛的文件名称
        String fileQiniuPath = ""; //七牛存储的路径
        try {
            FileInputStream inputStream = (FileInputStream) file.getInputStream();
            //上传七牛云服务器
            String qiniuPath = qiniuUtil.qiniuInputStreamUpload(inputStream, fileName);
            fileQiniuPath = qiniuUtil.getDownloadUrl("http://" + qiniuPath);//七牛存图片的路径
            String size=getPrintSize(file.getSize());//获取文件的大小
        } catch (Exception e) {
            log.error(e.toString());
            return new ResultUtil<Object>().setErrorMsg(300, "文件上传失败");
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("fileQiniuPath", fileQiniuPath);
        //压缩文件
        File excelFile=compressImage(file);
        //图片转化成base64字符串
        String strImg = GetImageStr(excelFile); 
        System.out.print(strImg);
        //replaceAll 处理一下base64串,去掉空格回车的\n\t等,不然不能将base64转换回图片
        jsonObject.put("strImg",strImg.replaceAll("[\\s*\t\n\r]", ""));
        //base64加密结束
        //文件使用结束时,删除生成的临时文件(上面new的newfile)
        RongyunPCController.deleteFile(newfile);
        return new ResultUtil<Object>().setData(jsonObject);

    }

     /**
     * 压缩MultipartFile图片
     * @param file
     * @return
     * @throws IOException
     */
    public static File compressImage(MultipartFile file) throws IOException {
        //压缩前台传过来的jpg图片开始(两种方法,取其一,一种生成临时文件(该方法操作删除临时文件时经常删不掉),一种可以删除的很干净)
        /**********在项目中生成临时文件方法开始**********/
        //String fileNames = "tupian.jpg";
        //在java中路径一般用"/"
        //windows中的路径一般用"\"
        //linux、unix中的路径一般用"/"
        //File newfile = new File("./", fileNames);
        /**********在项目中生成临时文件方法结束**********/
        /**********可以删除很干净的方法开始**********/
        // 获取文件名
        String fileNames=file.getOriginalFilename();
        // 获取文件后缀
         String prefix=fileName.substring(fileName.lastIndexOf("."));
        // 用uuid作为文件名,防止生成的临时文件重复
        final File newfile= File.createTempFile( System.currentTimeMillis()+"", prefix);
        try {
            // 先尝试压缩并保存图片
       InputStream in =file.getInputStream();//必须要先声明流,如果按照下面注释的方法写的话MultipartFile 文件会被占用,导致缓存在服务器上的文件不能执行删除Thumbnails.of(in).scale(0.5f).outputQuality(0.1f).toFile(excelFile);
            //Thumbnails.of(file.getInputStream()).size(20,20).keepAspectRatio(false).toFile(newfile); 根据长宽压缩
in.close();//关闭流
        } catch (Exception e) {
            // 失败了再用spring mvc自带的方
            file.transferTo(excelFile);
        }
        return excelFile;
    }

    /**
     * @Description: 删除文件
     * @params: [files] File...中的三个点作用为 如果不明确files入参具体有几个,可以用三个点代替,作用同数组差不多,该方法最好适用于后台内部的调用,各种类型都适用如String,File,Integer等,前台的如果是String类型,作用同数组集合等一模一样,但如果是integer类型的,前台入参就不太方便了
     * @return: void
     */
    private static void deleteFile(File... files) {
        for (File file : files) {
            if (file.exists()) {
                file.delete();
            }
        }
    }

//图片转化成base64字符串
    public static String GetImageStr(File file) {//将图片文件转化为字节数组字符串,并对其进行Base64编码处理
        InputStream in = null;
        byte[] data = null;
        //读取图片字节数组
        try {
            in = new FileInputStream(file);
            data=new byte[(int)file.length()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);//返回Base64编码过的字节数组字符串
    }

    //base64字符串转化成图片
    public static boolean GenerateImage(String imgStr) {   //对字节数组字符串进行Base64解码并生成图片
        if (imgStr == null) //图像数据为空
            return false;
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            byte[] b = Base64Utils.decode(imgStr.getBytes());
            //Base64解码
            //byte[] b = decoder.decodeBuffer(imgStr);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {//调整异常数据
                    b[i] += 256;
                }
            }
            //生成jpeg图片
            String imgFilePath = "C:\\Users\\18285\\Desktop\\new.jpg";//新生成的图片
            OutputStream out = new FileOutputStream(imgFilePath);
            out.write(b);
            out.flush();
            out.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

3.七牛的上传工具类

package cn.shangze.boot.common.utils;

import cn.shangze.boot.common.exception.XbootException;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Region;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import com.qiniu.util.UrlSafeBase64;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.UUID;

/**
 * @author leontius
 */
@Slf4j
@Component
public class QiniuUtil {

    /**
     * 生成上传凭证,然后准备上传,以下参数注册七牛后,七牛会给对应的参数,我们放在了配置文件中,用注解引入的,根据自己的项目来
     */
    @Value("${xboot.qiniu.accessKey}")
    private String accessKey; 

    @Value("${xboot.qiniu.secretKey}")
    private String secretKey;

    @Value("${xboot.qiniu.bucket}")
    private String bucket;

    @Value("${xboot.qiniu.domain}")
    private String domain;

    @Value("${xboot.qiniu.zone}")
    private Integer zone;

    /**
     * 构造一个带指定Zone对象的配置类 zone2华南
     */
//    public Configuration getConfiguration(){
//
//        Configuration cfg = null;
//        if(zone.equals(0)){
//            cfg = new Configuration(Zone.zone0());
//        }else if(zone.equals(1)){
//            cfg = new Configuration(Zone.zone1());
//        }else if(zone.equals(2)){
//            cfg = new Configuration(Zone.zone2());
//        }else if(zone.equals(3)){
//            cfg = new Configuration(Zone.zoneNa0());
//        }else if(zone.equals(4)){
//            cfg = new Configuration(Zone.zoneAs0());
//        }else {
//            cfg = new Configuration(Zone.autoZone());
//        }
//        return cfg;
//    }
    public Configuration getConfiguration(){
        Configuration cfg = null;
        if(zone.equals(0)){
            cfg = new Configuration(Region.region0());
        }else if(zone.equals(1)){
            cfg = new Configuration(Region.region1());
        }else if(zone.equals(2)){
            cfg = new Configuration(Region.region2());
        }else if(zone.equals(3)){
            cfg = new Configuration(Region.regionNa0());
        }else if(zone.equals(4)){
            cfg = new Configuration(Region.regionAs0());
        }else {
            cfg = new Configuration(Region.autoRegion());
        }
        return cfg;
    }

    public UploadManager getUploadManager(Configuration cfg){

        UploadManager uploadManager = new UploadManager(cfg);
        return uploadManager;
    }

    /**
     * 文件路径上传
     * @param filePath
     * @param key   文件名
     * @return
     */
    public String qiniuUpload(String filePath, String key) {

        Auth auth = Auth.create(accessKey, secretKey);
        String upToken = auth.uploadToken(bucket);
        try {
            Response response = getUploadManager(getConfiguration()).put(filePath, key, upToken);
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            return domain + "/" + putRet.key;
        } catch (QiniuException ex) {
            Response r = ex.response;
            throw new XbootException("上传文件出错,请检查七牛云配置," + r.toString());
        }
    }

    /**
     * 文件流上传
     * @param file
     * @param key  文件名
     * @return
     */
    public String qiniuInputStreamUpload(FileInputStream file, String key) {

        Auth auth = Auth.create(accessKey, secretKey);
        String upToken = auth.uploadToken(bucket);
        try {
            Response response = getUploadManager(getConfiguration()).put(file, key, upToken, null, null);
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            return domain + "/" + putRet.key;
        } catch (QiniuException ex) {
            Response r = ex.response;
            throw new XbootException("上传文件出错,请检查七牛云配置," + r.toString());
        }
    }

    /**
     * Base64上传
     * @param data64
     * @return
     */
    public String qiniuBase64Upload(String data64) {

        String key = renamePic("");
        // 服务端http://up-z2.qiniup.com 此处存储区域需自行修改
        String url = "http://up-z2.qiniup.com/putb64/-1/key/" + UrlSafeBase64.encodeToString(key);
        RequestBody rb = RequestBody.create(null, data64);
        Request request = new Request.Builder().
                url(url).
                addHeader("Content-Type", "application/octet-stream")
                .addHeader("Authorization", "UpToken " + getUpToken())
                .post(rb).build();
        OkHttpClient client = new OkHttpClient();
        okhttp3.Response response = null;
        try {
            response = client.newCall(request).execute();
        } catch (IOException e) {
            throw new XbootException("上传文件出错,请检查七牛云配置," + e.toString());
        }
        return domain + "/" + key;
    }

    public String getUpToken() {
        Auth auth = Auth.create(accessKey, secretKey);
        return auth.uploadToken(bucket, null, 3600, new StringMap().put("insertOnly", 1));
    }

    public String base64Data(String data) {

        if (data == null || data.isEmpty()) {
            return "";
        }
        String base64 = data.substring(data.lastIndexOf(",") + 1);
        return base64;
    }

    /**
     * 以UUID重命名
     *
     * @param fileName
     * @return
     */
    public String renamePic(String fileName) {
        String extName = fileName.substring(fileName.lastIndexOf("."));
        return UUID.randomUUID().toString().replace("-", "") + extName;
    }

    /**
     * 获取下载文件路径,即:donwloadUrl
     * @return
     */
    public String getDownloadUrl(String targetUrl) {
        //密钥配置
        Auth auth = Auth.create(accessKey, secretKey);
        // token过期时间为10年
        String downloadUrl = auth.privateDownloadUrl(targetUrl, 315360000);
        return downloadUrl;
    }

 /**
     * @Description: 自动转换文件大小单位
     * @auther: Hanweihu
     * @date: 11:04 2019/5/16
     * @param: [size]
     * @return: java.lang.String
     */
    public String getPrintSize(long size) {
        // 如果字节数少于1024,则直接以B为单位,否则先除于1024,后3位因太少无意义
        double value = (double) size;
        if (value < 1024) {
            return String.valueOf(value) + "B";
        } else {
            value = new BigDecimal(value / 1024).setScale(2,                 
            BigDecimal.ROUND_DOWN).doubleValue();
        }
        // 如果原字节数除于1024之后,少于1024,则可以直接以KB作为单位
        // 因为还没有到达要使用另一个单位的时候
        // 接下去以此类推
        if (value < 1024) {
            return String.valueOf(value) + "KB";
        } else {
            value = new BigDecimal(value / 1024).setScale(2, 
             BigDecimal.ROUND_DOWN).doubleValue();
        }
        if (value < 1024) {
            return String.valueOf(value) + "MB";
        } else {
            // 否则如果要以GB为单位的,先除于1024再作同样的处理
            value = new BigDecimal(value / 1024).setScale(2,     
              BigDecimal.ROUND_DOWN).doubleValue();
            return String.valueOf(value) + "GB";
        }
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值