当前位置 博文首页 > 盛夏温暖流年:Java 读取网络图片存储到本地并生成缩略图

    盛夏温暖流年:Java 读取网络图片存储到本地并生成缩略图

    作者:[db:作者] 时间:2021-07-13 15:54

    之前使用 Python 爬虫抓取电影网站信息作为自己网站的数据来源,其中包含的图片都是网络图片,会存在这样一个问题:

    当原始网站访问速度比较慢时,网站图片加载时间也会变得很慢,而且如果原始网站挂了,图片就直接访问不到了。

    此时的用户体验就很不好,所以对此进行了优化:

    每次后端启动时会默认开启任务先将未转换的网络图片存储到本地,再把网页中图片列表改为访问本地图片,这样就解决了加载慢的问题,也降低了和原始网站的耦合性,具体步骤如下:

    1.创建用于保存图片的文件夹

    我的保存路径:F:\images

    2.新建 createLocalImage 类用于图片转换

    package com.cn.beauty.task;
    
    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class createLocalImage {
    	// 需要保存到本地的根路径
        private static String basePath = "F:/";
    
        public static void main(String[] args) {
        	// 网页图片路径
            String destUrl = "http://5b0988e595225.cdn.sohucs.com/images/20200215/349bb3cb88b744dcb67f37dba2f71abf.jpeg";
            String filePath = createLocalImageMethod(destUrl);
            System.out.println("生成的相对文件路径为" + filePath);
        }
    
        private static String createLocalImageMethod(String destUrl) {
            FileOutputStream fos = null;
            BufferedInputStream bis = null;
            HttpURLConnection httpUrl = null;
            URL url = null;
            int BUFFER_SIZE = 1024;
            byte[] buf = new byte[BUFFER_SIZE];
            int size = 0;
            String filePath = "";
            try {
                System.out.println("原始图片URL为:" + destUrl);
                String[] fileNameArray = destUrl.split("\\/");
                if (fileNameArray.length > 1) {
                    String fileName = fileNameArray[fileNameArray.length - 1];
                    filePath = "images/" + fileName;
                    File file = new File(basePath + filePath);
                    if (!file.exists()) {
                        url = new URL(destUrl);
                        httpUrl = (HttpURLConnection) url.openConnection();
                        httpUrl.connect();
                        bis = new BufferedInputStream(httpUrl.getInputStream());
                        fos = new FileOutputStream(basePath + filePath);
                        while ((size = bis.read(buf)) != -1) {
                            fos.write(buf, 0, size);
                        }
                        fos.flush();
                    }
                    // 后续对图片进行缩略图处理,见后面代码
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassCastException e) {
                e.printStackTrace();
            } finally {
                try {
                    fos.close();
                    bis.close();
                    httpUrl.disconnect();
                } catch (IOException e) {
                } catch (NullPointerException e) {
                }
            }
            return filePath;
        }
    }
    
    

    运行后发现图片已经成功生成:

    在这里插入图片描述
    3.生成缩略图

    如果是图片列表的展示,原始图片过大还是会影响加载速度,此时我们可以将图片处理为缩略图进行显示。

    我们使用了一个很强大的图片处理工具类:Thumbnails,它支持的功能包括:

    • 按指定大小进行缩放;
    • 按照比例进行缩放;
    • 不按照比例,指定大小进行缩放;
    • 旋转,水印,裁剪;
    • 转化图像格式;
    • 输出到 OutputStream;
    • 输出到 BufferedImage;

    这里的需求比较简单,只用到了按指定大小进行缩放的功能。

    引入对应 jar 包:

    <dependency>
          <groupId>net.coobird</groupId>
          <artifactId>thumbnailator</artifactId>
          <version>0.4.8</version>
    </dependency>
    

    在 createLocalImage 方法中添加缩略图生成的代码实现:

    	String thumbName = fileName.split("\\.")[0] + "_thumb." + fileName.split("\\.")[1];
        String thumbPath = basePath + filePath.replace(fileName, thumbName);
        //将要转换出的小图文件
        File fo = new File(thumbPath);
        if (fo.exists()) {
             return thumbPath;
        }
        // 第一个参数是原始图片的路径,第二个是缩略图的路径
        Thumbnails.of(basePath + filePath).size(120, 120).toFile(thumbPath);
        System.out.println("生成的缩略图路径为:" + thumbPath);
    

    再次运行,发现缩略图已经成功生成:
    在这里插入图片描述

    cs