Java 读取网络图片存储到本地并生成缩略图
之前使用 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; }}
运行后发现图片已经成功生成:
如果是图片列表的展示,原始图片过大还是会影响加载速度,此时我们可以将图片处理为缩略图进行显示。
我们使用了一个很强大的图片处理工具类: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:testtest.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 图片存储到本地并生成缩略图的资料请关注好吧啦网其它相关文章!
相关文章:
