java 网络图片压缩、富文本图片提取、获取图片MB大小、图片File按比例压缩并重命名、图片File转MultipartFile对象并上传到接口工具类

这是一个Java工具类,用于处理网络图片:从URL加载图片到本地,根据大小进行压缩,重命名,转换为MultipartFile并上传到服务器。类包括网络图片加载、文件大小转换、图片压缩、MultipartFile转换和上传等功能。

业务模型

  1. 已知图片网络图片url(或一段含有图片的富文本)。
  2. 通过图片url加载图片到本地(或者读取富文本中的img属性解析图片url)(使用方法 getFileByNetUrlHttp、getImgStr)。
  3. 获取文件大小并转换为MB(使用formatFileSize)
  4. 如果文件大于一定大小(fileMaxVlue)按照比例(reduce)压缩通过url加载的本地图片,并重命名(方法renameAndReduceFile)。
  5. 图片压缩完成之后转换成MultipartFile并提交到上传接口(uploadPostUrl ),删除压缩后的本地图片(sendMultipartFilePost)。

工具类主要功能

  • 网络图片加载到本地Fille(getFileByNetUrlHttp)
  • 获取文件File大小,并转换为MB单位(formatFileSize)
  • 图片按照比例压缩成新文件File,重命名(renameAndReduceFile)
  • 图片File转换为MultipartFile对象(getMultipartFile)
  • 提交MultipartFile对象到图片上传接口(sendMultipartFilePost)
  • 富文本中提取图片(img标签src属性)(getImgStr)

工具类源码

package com.shipj.test.util;

import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.mock.web.MockMultipartFile;

import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author shipj
 * @version 1.0
 * @Title: ProductpPcturesDealUtil
 * @Description: 图片压缩并接口上传工具类(业务模型,从图片url(从图片url或富文本中包含url)加载图片到本,本地进行压缩图片,压缩完成之后通过接口上传到服务)
 * @date 2021-04-09 16:19
 */
@Slf4j
public class ProductpPcturesDealUtil {

    //压缩比例
    private static float reduce = 0.3f;

    //文件临时目录
    private static String fileDir = "D:\\TEMP\\";

    //上传图片url
    private static String uploadPostUrl = "https://127.0.0.1:8080/test/storage/putFile";

    //上传文件名称
    private static String fileParName = "file";

    //需压缩文件界值
    public static float fileMaxVlue = 5f;

    //img Matcher 对象
    private static Pattern p_image=Pattern.compile("<img.*src\\s*=\\s*(.*?)[^>]*?>",Pattern.CASE_INSENSITIVE);

    //img src Matcher 对象
    private static Pattern r_image=Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)");

    /**
     * @return float
     * @Author shipj
     * @Description 转换文件大小(MB)
     * @Date 10:58 2021-04-09
     * @Param [fileLength] file length
     **/
    public static float formatFileSize(long fileLength) {
        if (fileLength == 0) {
            return 0;
        }
        //运算转换单位(保留2位小数)
        float mbUnit = 1048676;
        float mbValue = ((float) fileLength) / mbUnit;
        //转换单位为MB
        float fileSizeMB = new BigDecimal(mbValue).setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
        return fileSizeMB;
    }


    /**
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @Author shipj
     * @Description 根据图片url全路径获取File对象信息
     * @Date 10:57 2021-04-09
     * @Param [netUrl] 图片url
     **/
    public static Map<String, Object> getFileByNetUrlHttp(String netUrl) {
        //构建file对象返回所需参数
        Map<String, Object> result = new HashMap<>();
        //对本地文件命名,path是http的完整路径,主要得到资源的名字
        String newUrl = netUrl;
        newUrl = newUrl.split("[?]")[0];
        String[] arraySlash = newUrl.split("/");
        //得到最后一个分隔符后的名字
        String fileName = arraySlash[arraySlash.length - 1];
        //获取文件后缀名
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);


        //保存到本地的路径
        String filePath = fileDir + fileName;

        File file = null;
        URL urlfile = null;
        //判断文件的父级目录是否存在,不存在则创建
        file = new File(filePath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        try {
            //创建文件
            file.createNewFile();
        } catch (Exception e) {
            result.put("code", 1);
            result.put("msg", "file.createNewFile 异常,异常信息:" + e.getMessage());
        }
        try {
            urlfile = new URL(newUrl);
        } catch (MalformedURLException e) {
            result.put("code", 1);
            result.put("msg", "URL 异常,异常路径:" + e.getMessage());
        }
        HttpURLConnection huc = null;
        try {
            huc = (HttpURLConnection) urlfile.openConnection();
        } catch (IOException e) {
            result.put("code", 1);
            result.put("msg", "huc 异常:" + e.getMessage());
        }
        //从HTTP响应消息获取状态码,如果响应成功,则处理图片
        int code = 0;
        try {
            code = huc.getResponseCode();
        } catch (IOException e) {
            result.put("code", 1);
            result.put("msg", "huc.getResponseCode 异常:" + e.getMessage());
        }
        if (code == 200) {
            InputStream inputStream = null;
            OutputStream outputStream = null;
            //下载
            try {
                inputStream = urlfile.openStream();
            } catch (IOException e) {
                result.put("code", 1);
                result.put("msg", "inputStream 异常,异常信息:" + e.getMessage());
            }
            try {
                outputStream = new FileOutputStream(file);
            } catch (FileNotFoundException e) {
                result.put("code", 1);
                result.put("msg", "outputStream 异常,异常信息:" + e.getMessage());
            }

            int bytesRead = 0;
            byte[] buffer = new byte[1024];
            while (true) {
                try {
                    if (!((bytesRead = inputStream.read(buffer, 0, 1024)) != -1)) {
                        break;
                    }
                    outputStream.write(buffer, 0, bytesRead);
                } catch (IOException e) {
                    result.put("code", 1);
                    result.put("msg", "outputStream.write 异常,异常信息:" + e.getMessage());
                    break;
                }
            }
            //关闭输入输出流
            try {
                if (null != outputStream) {
                    outputStream.close();
                }
                if (null != inputStream) {
                    inputStream.close();
                }
            } catch (IOException e) {
                result.put("code", 1);
                result.put("msg", "outputStream.close/inputStream.close 异常,异常信息 :" + e.getMessage());
            }
            //判断文件大小
            float fileSize = formatFileSize(file.length());
            log.info(fileName + " 文件大小:" + fileSize);

            result.put("fileSize", fileSize);
            result.put("fileMaxVlue", fileMaxVlue);
            result.put("code", 0);
            result.put("msg", "");
        } else {
            result.put("code", 1);
            result.put("msg", "无法正常访问地址:" + netUrl);
        }

        result.put("fileDir", fileDir);
        result.put("filePath", filePath);
        result.put("fileName", fileName);
        result.put("suffix", suffix);
        result.put("file", file);
        log.info("图片转化文件成功");
        return result;
    }


    /**
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @Author shipj
     * @Description 图片重命名并压缩处理
     * @Date 11:27 2021-04-09
     * @Param [path, oldname, newname]
     **/
    public static Map<String, Object> renameAndReduceFile(String path, String oldname, String newname) {
        //构建file对象返回所需参数
        Map<String, Object> result = new HashMap<>();
        if (!oldname.equals(newname)) {//新的文件名和以前文件名不同时,才有必要进行重命名
            String oldFilePath = path + File.separator + oldname;
            String newFilePath = path + File.separator + newname;
            File oldfile = new File(oldFilePath);
            File newfile = new File(newFilePath);
            if (!oldfile.exists()) {
                log.info(oldname + "重命名文件不存在!");
                //重命名文件不存在
                result.put("code", 1);
                result.put("msg", "重命名文件不存在");
                return result;
            }
            if (newfile.exists()) {
                //若在该目录下已经有一个文件和新文件名相同,则不允许重命名
                log.info(newname + "已经存在!");
                result.put("code", 1);
                result.put("msg", newname + "已经存在!");
                return result;
            } else {
                try {
                    //压缩图片
                    Thumbnails.of(oldfile).scale(1).outputQuality(reduce).toFile(newfile);
                    //删除原有文件
                    oldfile.deleteOnExit();
                } catch (IOException e) {
                    log.info("压缩文件发生异常:" + e.getMessage());
                }
                oldfile.renameTo(newfile);
                result.put("code", 0);
                result.put("msg", "");
                result.put("newFile", newfile);
                result.put("newFileName", newname);
                result.put("newFileDir", path);
                result.put("newFilePath", newFilePath);
                log.info("重命名文件并压缩文件成功");
                return result;
            }
        } else {
            log.info("新文件名和旧文件名相同...");
            result.put("code", 1);
            result.put("msg", "新文件名和旧文件名相同");
            return result;
        }
    }


    /**
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @Author shipj
     * @Description 将本地文件转换为MultipartFile
     * @Date 11:51 2021-04-09
     * @Param [file]
     **/
    public static Map<String, Object> getMultipartFile(File file) {
        //构建file对象返回所需参数
        Map<String, Object> result = new HashMap<>();
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);
            MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(),
                    ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);

            result.put("code", 0);
            result.put("multipartFile", multipartFile);
            log.info("转换 MultipartFile 成功");
            return result;
        } catch (IOException e) {
            result.put("code", 1);
            result.put("msg", "转换 MultipartFile 失败,异常信息:" + e.getMessage());
            return result;
        } finally {
            try {
                if (null != inputStream) {
                    inputStream.close();
                }
            } catch (IOException e) {
                result.put("code", 1);
                result.put("msg", "转换 MultipartFile 文件流关闭失败,异常信息:" + e.getMessage());
                return result;
            }
        }
    }


    /***
     * @Author shipj
     * @Description 构建文件上传请求,并返回结果
     * @Date 13:51 2021-04-09
     * @Param [multipartFile, file,params]
     * @return java.util.Map<java.lang.String, java.lang.Object>
     **/
    public static Map<String, Object> sendMultipartFilePost(MultipartFile multipartFile, File file, Map<String, Object> params) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String result = "";
        try {
            HttpPost httpPost = new HttpPost(uploadPostUrl);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setCharset(java.nio.charset.Charset.forName("UTF-8"));
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            String fileName = null;
            fileName = multipartFile.getOriginalFilename();
            builder.addBinaryBody(fileParName, multipartFile.getBytes(), ContentType.MULTIPART_FORM_DATA, fileName);// 文件流
            //解决中文乱码
//            ContentType contentType = ContentType.create(HTTP.PLAIN_TEXT_TYPE, HTTP.UTF_8);
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                if (entry.getValue() == null) {
                    continue;
                }
                // 类似浏览器表单提交,对应input的name和value
                builder.addTextBody(entry.getKey(), entry.getValue().toString());
            }
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);// 执行提交

            // 设置连接超时时间
//            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout)
//                    .setConnectionRequestTimeout(timeout).setSocketTimeout(timeout).build();
//            httpPost.setConfig(requestConfig);

            HttpEntity responseEntity = response.getEntity();
            int code = response.getStatusLine().getStatusCode() == 200 ? 0 : 1;
            if (code == 0) {
                resultMap.put("code", code);
                resultMap.put("msg", String.valueOf(response.getStatusLine().getStatusCode()));
                if (responseEntity != null) {
                    // 将响应内容转换为字符串

                    result = EntityUtils.toString(responseEntity, java.nio.charset.Charset.forName("UTF-8"));
                    log.info("构建文件上传请求,上传成功返回 result :" + result);
                    resultMap.put("msg", result);
                    ((CloseableHttpResponse) response).close();
                } else {
                    resultMap.put("code", 1);
                    resultMap.put("msg", "构建文件上传请求,HTTP请求出现返回 responseEntity 为空");
                }
            } else {
                log.info("构建文件上传请求,返回非 200 code :" + String.valueOf(response.getStatusLine().getStatusCode()));
                resultMap.put("code", code);
                resultMap.put("msg", String.valueOf(response.getStatusLine().getStatusCode()));
            }
            httpPost.releaseConnection();
            httpClient.close();
        } catch (Exception e) {
            log.info("构建文件上传请求,HTTP请求出现异常:" + e.getMessage());
            resultMap.put("code", 1);
            resultMap.put("msg", "构建文件上传请求,HTTP请求出现异常: " + e.getMessage());
        } finally {
            //删除源文件
            file.deleteOnExit();
        }

        return resultMap;
    }

    
    /**
     * @Author shipj
     * @Description 提取富文本图片(img标签src属性)
     * @Date 20:49 2021-04-12
     * @Param [htmlStr]
     * @return java.util.List<java.lang.String>
     **/
    public static List<String> getImgStr(String htmlStr) {
        List<String> list = new ArrayList<>();
        String regEx_img = "<img.*src\\s*=\\s*(.*?)[^>]*?>";
        Matcher m_image = p_image.matcher(htmlStr);
        while (m_image.find()) {
            // 得到<img />数据
            String img = m_image.group();
//            System.out.println(img);
            // 匹配<img>中的src数据
            Matcher m = r_image.matcher(img);
            while (m.find()) {
                list.add(m.group(1));
            }
        }
        return list;
    }


    /**
     * @Author shipj
     * @Description 提取富文本中纯文本
     * @Date 20:42 2021-04-12
     * @Param [richText]
     * @return java.lang.String
     **/
    public static String getText(String richText) {
        String regx = "(<.+?>)|(</.+?>)";
        Matcher matcher = Pattern.compile(regx).matcher(richText);
        while (matcher.find()) {
            // 替换图片
            richText = matcher.replaceAll("").replace(" ", "");
        }
        return richText;
    }

}
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

spjhandsomeman

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值