之前使用 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

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

我们使用了一个很强大的图片处理工具类: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);

再次运行,发现缩略图已经成功生成:

另一种方法

直接将下面的代码封装成一个util即可,调用示例在main方法中,调用的地方需要引入import java.awt.image.bufferedimage;,还要确保旧文件是存在的

import java.awt.image.bufferedimage;
import java.io.file;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.util.hashmap;
import java.util.map;
import javax.imageio.imageio;
import com.sun.image.codec.jpeg.jpegcodec;
import com.sun.image.codec.jpeg.jpegencodeparam;
import com.sun.image.codec.jpeg.jpegimageencoder;
public class resizeimage {
    public static void main(string[] args) throws ioexception {
        //windows路径,linux环境下相应修改
        string outputfolder = "d:\\test\\";
        string filename = "d:\\test\\test.jpg";
        resizeimage r = new resizeimage();
        int towidth=220,toheight=220;
        bufferedimage imagelist = r.getimagelist(filename,new string[] {"jpg","png","gif"});
        r.writehighquality("newfile.jpg",r.zoomimage(imagelist,towidth,toheight),outputfolder);
    }
    /**
     * @description: 取得图片对象
     * @param 要转化的图像的文件夹,就是存放图像的文件夹路径
     * @date 2017年5月7日10:48:27
     */
    public bufferedimage zoomimage(bufferedimage im, int towidth , int toheight) {
        bufferedimage result = new bufferedimage(towidth, toheight, bufferedimage.type_int_rgb);
        result.getgraphics().drawimage(im.getscaledinstance(towidth, toheight, java.awt.image.scale_smooth), 0, 0, null);
        return result;
    }
    /**
     * @description: 取得图片对象
     * @param 要转化的图像的文件夹,就是存放图像的文件夹路径
     * @date 2017年5月7日10:48:27
     */
    public bufferedimage getimagelist(string imglist, string[] type) throws ioexception{
        map<string,boolean> map = new hashmap<string, boolean>();
        for(string s : type) {
            map.put(s,true);
        }
        bufferedimage imagelist = null;
        file file = null;
        file = new file(imglist);
        try{
            if(file.length() != 0 && map.get(getextension(file.getname())) != null ){
                imagelist = javax.imageio.imageio.read(file);
            }
        }catch(exception e){
            imagelist = null;
        }
        return imagelist;
    }
    /**
     * 把图片写到磁盘上
     * @param im
     * @param path      图片写入的文件夹地址
     * @param filename  写入图片的名字
     * @date 2017年5月7日10:48:27
     */
    public boolean writetodisk(bufferedimage im, string path, string filename) {
        file f = new file(path + filename);
        string filetype = getextension(filename);
        if (filetype == null)
            return false;
        try {
            imageio.write(im, filetype, f);
            im.flush();
            return true;
        } catch (ioexception e) {
            return false;
        }
    }
    /**
     * @description: 生成图片
     * @param string path , bufferedimage im, string filefullpath
     * @date 2017年5月7日10:48:27
     */
    public boolean writehighquality(string path , bufferedimage im, string filefullpath) throws ioexception {
        fileoutputstream newimage = null;
        try {
            // 输出到文件流
            newimage = new fileoutputstream(filefullpath+path);
            jpegimageencoder encoder = jpegcodec.createjpegencoder(newimage);
            jpegencodeparam jep = jpegcodec.getdefaultjpegencodeparam(im);
            // 压缩质量
            jep.setquality(1f, true);
            encoder.encode(im, jep);
            //近jpeg编码
            newimage.close();
            return true;
        } catch (exception e) {
            return false;
        }
    }
    /**
     * @description: 取文件名的后缀
     * @param string filename 格式如:cn1100000213ea_1_xnl.jpg
     * @date 2017年5月7日10:48:27
     */
    public string getextension(string filename) {
        try {
            return filename.split("\\.")[filename.split("\\.").length - 1];
        } catch (exception e) {
            return null;
        }
    }

以上就是java 读取网络图片存储到本地并生成缩略图的详细内容,更多关于java 图片存储到本地并生成缩略图的资料请关注www.887551.com其它相关文章!