Java 讀取網(wǎng)絡(luò)圖片存儲到本地并生成縮略圖
之前使用 Python 爬蟲抓取電影網(wǎng)站信息作為自己網(wǎng)站的數(shù)據(jù)來源,其中包含的圖片都是網(wǎng)絡(luò)圖片,會存在這樣一個問題:
當原始網(wǎng)站訪問速度比較慢時,網(wǎng)站圖片加載時間也會變得很慢,而且如果原始網(wǎng)站掛了,圖片就直接訪問不到了。
此時的用戶體驗就很不好,所以對此進行了優(yōu)化:
每次后端啟動時會默認開啟任務先將未轉(zhuǎn)換的網(wǎng)絡(luò)圖片存儲到本地,再把網(wǎng)頁中圖片列表改為訪問本地圖片,這樣就解決了加載慢的問題,也降低了和原始網(wǎng)站的耦合性,具體步驟如下:
1.創(chuàng)建用于保存圖片的文件夾
我的保存路徑:F:\images
2.新建 createLocalImage 類用于圖片轉(zhuǎn)換
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) {
// 網(wǎng)頁圖片路徑
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();
}
// 后續(xù)對圖片進行縮略圖處理,見后面代碼
}
} 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;
}
}
運行后發(fā)現(xiàn)圖片已經(jīng)成功生成:

3.生成縮略圖
使用工具類Thumbnails
如果是圖片列表的展示,原始圖片過大還是會影響加載速度,此時我們可以將圖片處理為縮略圖進行顯示。
我們使用了一個很強大的圖片處理工具類:Thumbnails,它支持的功能包括:
- 按指定大小進行縮放;
- 按照比例進行縮放;
- 不按照比例,指定大小進行縮放;
- 旋轉(zhuǎn),水印,裁剪;
- 轉(zhuǎn)化圖像格式;
- 輸出到 OutputStream;
- 輸出到 BufferedImage;
這里的需求比較簡單,只用到了按指定大小進行縮放的功能。
引入對應 jar 包:
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
在 createLocalImage 方法中添加縮略圖生成的代碼實現(xiàn):
String thumbName = fileName.split("\\.")[0] + "_thumb." + fileName.split("\\.")[1];
String thumbPath = basePath + filePath.replace(fileName, thumbName);
//將要轉(zhuǎn)換出的小圖文件
File fo = new File(thumbPath);
if (fo.exists()) {
return thumbPath;
}
// 第一個參數(shù)是原始圖片的路徑,第二個是縮略圖的路徑
Thumbnails.of(basePath + filePath).size(120, 120).toFile(thumbPath);
System.out.println("生成的縮略圖路徑為:" + thumbPath);
再次運行,發(fā)現(xiàn)縮略圖已經(jīng)成功生成:

另一種方法
直接將下面的代碼封裝成一個util即可,調(diào)用示例在main方法中,調(diào)用的地方需要引入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環(huán)境下相應修改
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 要轉(zhuǎn)化的圖像的文件夾,就是存放圖像的文件夾路徑
* @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 要轉(zhuǎn)化的圖像的文件夾,就是存放圖像的文件夾路徑
* @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);
// 壓縮質(zhì)量
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 讀取網(wǎng)絡(luò)圖片存儲到本地并生成縮略圖的詳細內(nèi)容,更多關(guān)于Java 圖片存儲到本地并生成縮略圖的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java中一個線程執(zhí)行死循環(huán)有什么后果
這篇文章主要為大家詳細介紹了Java中一個線程執(zhí)行死循環(huán)有什么后果,當一個線程在執(zhí)行死循環(huán)時會影響另外一個線程嗎,下面為大家揭曉2016-05-05
基于Springboot實現(xiàn)定時發(fā)送郵件功能
這篇文章主要為大家詳細介紹了基于Springboot實現(xiàn)定時發(fā)送郵件功能的相關(guān)知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2024-03-03
Servlet和Filter之間的區(qū)別與聯(lián)系
這篇文章主要介紹了Servlet和Filter之間的區(qū)別與聯(lián)系的相關(guān)資料,需要的朋友可以參考下2016-05-05
EasyExcel自定義下拉注解的三種實現(xiàn)方式總結(jié)
使用EasyExcel設(shè)置下拉數(shù)據(jù)時,每次都要創(chuàng)建一個SheetWriteHandler組件確實比較繁瑣,為了優(yōu)化這個過程,我們可以通過自定義注解來簡化操作,下面就來看看具體實現(xiàn)方法吧2024-10-10

