下载多张图片并压缩成压缩包

news/2024/7/7 20:54:03

工具类

package com.manage.util;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 图片下载工具类
 */
public class ImageDownloadUtil {

    /**
     * 下载多张图片的压缩包
     * @param request
     * @param response
     * @param imgUrlStr 多张图片URL地址逗号拼接字符串
     * @param zipName 压缩包名称
     * @throws Exception
     */
    public static void downloadImagesZip(HttpServletRequest request, HttpServletResponse response, String imgUrlStr,String zipName) throws Exception {
        downloadImagesZip(request, response, imgUrlStr.split(","), zipName);
    }

    /**
     * 下载多张图片的压缩包
     * @param request
     * @param response
     * @param imgUrlList 多张图片URL地址list集合
     * @param zipName 压缩包名称
     * @throws Exception
     */
    public static void downloadImagesZip(HttpServletRequest request, HttpServletResponse response, List imgUrlList, String zipName) throws Exception {
        Integer size = imgUrlList == null ? 10 : imgUrlList.size();
        downloadImagesZip(request, response, (String[]) imgUrlList.toArray(new String[size]), zipName);
    }

    /**
     * 下载多张图片的压缩包
     * @param request
     * @param response
     * @param imgUrls 多张图片URL地址数组
     * @param zipName 压缩包名称
     * @throws Exception
     */
    public static void downloadImagesZip(HttpServletRequest request, HttpServletResponse response, String[] imgUrls,String zipName) throws Exception {
        // 获取多张图片的二进制
        byte [] data = getImagesByte(imgUrls);

        response.reset();
        response.setHeader("Content-Disposition", "attachment; filename=\"" + zipName + ".zip\"");
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");

        IOUtils.write(data, response.getOutputStream());
        IOUtils.closeQuietly(response.getOutputStream());
    }


    /**
     * 获取多张图片的二进制
     * @param imgUrls 多张图片URL地址数组
     * @return
     * @throws Exception
     */
    public static byte[] getImagesByte(String[] imgUrls) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);

        for (String imgUrl : imgUrls) {
            // 获取图片名称
            String imgName = imgUrl.substring(imgUrl.lastIndexOf("/")+1);
            String imageName = imgName.substring(0,imgName.lastIndexOf("."));

            // 将当前的图片放到zip流中传出去
            downLoadImage(imgUrl, imageName, zipOutputStream);
        }

        IOUtils.closeQuietly(zipOutputStream);
        return outputStream.toByteArray();
    }

    /**
     * 将当前的图片放到zip流中传出去
     * @param imageUrl 图片URL地址
     * @param imageName 图片名称
     * @param zipOutputStream zip输出流
     */
    public static void downLoadImage(String imageUrl,String imageName,ZipOutputStream zipOutputStream) {
        String imgArray[] = {"jpg","png","gif","bmp","jpeg"};
        List suffixList = Arrays.asList(imgArray);
        String suffix = imageUrl.substring(imageUrl.lastIndexOf(".") + 1);

        if(StringUtils.isNotBlank(imageUrl)){
            BufferedInputStream in = null;
            try {
                //校验读取到文件
                if (!suffixList.contains(suffix)) {
                    // 文件格式不对
                    throw new Exception("不是图片");
                }

                imageName += "." + suffix;

                URL url = new URL(imageUrl);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setConnectTimeout(5 * 1000);
                conn.setRequestMethod("GET");
                conn.setRequestProperty(
                        "Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
                                + "application/x-shockwave-flash, application/xaml+xml, "
                                + "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
                                + "application/x-ms-application, application/vnd.ms-excel, "
                                + "application/vnd.ms-powerpoint, application/msword, */*");
                conn.setRequestProperty("Accept-Language", "zh-CN");
                conn.setRequestProperty("Charset", "UTF-8");

                InputStream inStream = conn.getInputStream();
                if(inStream == null) {
                    throw new Exception("获取压缩的数据项失败! 图片名为:" + imageName);
                }else {
                    in = new BufferedInputStream(inStream);
                }

                // 压缩条目不是具体独立的文件,而是压缩包文件列表中的列表项,称为条目,就像索引一样
                //ZipEntry zipEntry = new ZipEntry("图片/" + imageName);

                ZipEntry zipEntry = new ZipEntry(imageName);
                // 定位到该压缩条目位置,开始写入文件到压缩包中
                zipOutputStream.putNextEntry(zipEntry);

                byte[] bytes = new byte[1024 * 5]; // 读写缓冲区
                int read = 0;
                while ((read = in.read(bytes)) != -1) {
                    zipOutputStream.write(bytes, 0, read);
                }

                IOUtils.closeQuietly(inStream); // 关掉输入流
                IOUtils.closeQuietly(in); // 关掉缓冲输入流
                zipOutputStream.closeEntry();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

测试

@RequestMapping("/getImg")
public void getImg(HttpServletRequest request, HttpServletResponse response) {
    ArrayList<String> urlList = new ArrayList<>();
    urlList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1554790861898&di=d6919516aebaab4a5133439671672934&imgtype=0&src=http%3A%2F%2Fimg2.3lian.com%2F2014%2Ff4%2F158%2Fd%2F105.jpg");
    try {
        ImageDownloadUtil.downloadImagesZip(request,response,urlList,"image");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

结果
在这里插入图片描述


http://www.niftyadmin.cn/n/2257134.html

相关文章

sklearn的train_test_split

train_test_split函数用于将矩阵随机划分为训练子集和测试子集&#xff0c;并返回划分好的训练集测试集样本和训练集测试集标签。 格式&#xff1a; X_train,X_test, y_train, y_test cross_validation.train_test_split(train_data,train_target,test_size0.3, random_state0)…

Spring Cloud Gateway过滤器工厂GatewayFilterFactory初探

1. 概述 在【spring cloud gateway】的官方文档中&#xff0c;是这样说明GatewayFilterFactory的&#xff1a; Route filters allow the modification of the incoming HTTP request or outgoing HTTP response in some manner. Route filters are scoped to a particular rout…

计算机系统管理内存的大小是由什么决定的,请问行家,电脑的虚拟内存是什么,它的大小由什么决定 爱问知识人...

虚拟内存用硬盘空间做内存来弥补计算机RAM空间的缺乏。当实际RAM满时(实际上&#xff0c;在RAM满之前)&#xff0c;虚拟内存就在硬盘上创建了。当物理内存用完后&#xff0c;虚拟内存管理器选择最近没有用过的&#xff0c;低优先级的内存部分写到交换文件上。这个过程对应用是隐…

Netflix开发者大赛,云计算1.0,还是2.0?

Joe Emison是BuildFax公司的CTO和创始人&#xff0c;该公司为企业提供地产方面的数据&#xff0c;在技术架构上以云计算为基础。最近&#xff0c;Joe Emsion在信息周刊上发表文章《Netflix如何毁掉云计算》&#xff0c;指责Netflix最近举办的云计算开发者大赛抱有“以AWS为中心…

XXL-JOB框架

目录【简介】【入门篇】【使用篇】【总结】【简介】 轻量级分布式任务调度平台: 官网&#xff1a; http://www.xuxueli.com/xxl-job/#/ 【入门篇】 官网的文档写的非常详细&#xff0c;可以参考官方文档的步骤进行部署。这里大概的记录下大概的步骤 1、下载源码 2、解压并…

内容页fragment注意事项

###类似新闻内容页,viewpager加载多个fragment并且经常切换的需求,这种情况下的内存需要特别注意&#xff0c;一不小心处理不当很容易出现内存暴涨&#xff0c;频繁触发gc页面卡顿&#xff0c;甚至oom的情况&#xff0c;针对这种需求总结下面几点注意事项 ###注意事项 1.采用Fr…

多线程【汇总】

目录【并发编程】【多线程】【线程池】【并发编程】 【并发编程源码系列】 Java并发指南 Java并发编程系列文章目录帖及源码 Java并发编程源码详解 【socket】 socket 【如何控制线程执行顺序】 如何控制线程执行顺序 【多线程】 【关于线程中的sleep&#xff0c;wait&…

什么是阿里云容器服务?

2019独角兽企业重金招聘Python工程师标准>>> 关于阿里云容器服务的详细内容&#xff1a;阿里云容器服务使用教程 容器服务&#xff08;Container Service&#xff09;提供高性能可伸缩的容器应用管理服务&#xff0c;支持用 Docker 容器进行应用生命周期管理&#x…