对我使用过的前端显示图片的方法进行小总结,作为以后参考的依据。
说在前面的话:关于这几种实现方式,有可能原理是一样的,而且肯定有更优的实现方式。因为时间关系我没有进行深入研究,如果哪里写的不对,请多多指教。
目前,共接触以下几类方法:
1.img标签指向图片地址
<img border="0" src="picture.jpg" alt="picture" width="160" height="100">
2.img标签指向servlet方法
<img border="0" src="/ImgServlet?imgId=00001" alt="picture" width="160" height="100">
其中,ImgServlet就是一个简单的Servlet:根据imgId读取相应图片,并通过输出流写到response中。实现方式有很多种,这里只给出一代代码作为示例:
代码只是显示大致的实现流程,并不保证正确。
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//获取图片id
String imgId = request.getParameter("imgId");
//查询数据库得到图片路径
String imagePath = getImagePathFromDB(imgId);
//重置response
response.reset();
//得到输出流
OutputStream output = response.getOutputStream();
//设置contenttype
response.setContentType(GIF);
ServletContext context = getServletContext();
//读取文件流
InputStream imageIn = context.getResourceAsStream(imagePath);
//输入缓冲流
BufferedInputStream bis = new BufferedInputStream(imageIn);
//输出缓冲流
BufferedOutputStream bos = new BufferedOutputStream(output);
// 缓冲字节数
byte data[] = new byte[4096];
int size = 0;
size = bis.read(data);
while (size != -1) {
bos.write(data, 0, size);
size = bis.read(data);
}
bis.close();
bos.flush();
bos.close();
output.close();
}
除了这种最基础的文件读流写流,还要一些更专用的类等,如javax.imageio.ImageIO等包专门用来操作图片。如果感兴趣,可以自行了解。
3.img标签指向base64流
<img src="https://img-blog.csdnimg.cn/2022010706463773757.gif">
关于base64图片流,有几点说明:
base64加密,大小增长1/3左右。
base64流显示图片,能够减少一个图片的 HTTP 请求,适合小图片。
base64流显示图片,大图片渲染解析得比较慢,不适合大图片。
base64流显示图片,IE 8 以下不支持 data url,IE 8 开始支持 data url,却有大小限制,32k(未测试)。
4.通过HTTP请求以内联方式下载图片
通过response.setHeader()方法,将Content-Disposition设置为inline类型。
inline,即内联,即在浏览器打开所下载的图片,即显示图片。
实现方式可以参考Spring MVC代码实例系列-10:Spring MVC实现简单的文件上传和下载。
这里只给出关键代码作为参考:
//获取文件类型
String mimeType = URLConnection.guessContentTypeFromName(file.getName());
//如果文件类型为空,则使用默认文件类型
if (null == mimeType){
mimeType = "application/octet-stream";
}
LOGGER.debug("mimeType:" + mimeType);
//设置contentType
response.setContentType(mimeType);
/*
设置文件下载方式:
1.inline:浏览器内打开此文件(如txt、xml等),不能打开的再下载(如rar等)
2.attachment:下载文件到本地
*/
response.setHeader("Content-Disposition",type + ";filename=\"" + file.getName() + "\"");
//设置长度
response.setContentLength((int) file.length());
//下载文件
InputStream inputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream(file));
FileCopyUtils.copy(inputStream,response.getOutputStream());
inputStream.close();
response.getOutputStream().close();
} catch (FileNotFoundException e) {
e.printStackTrace();
LOGGER.error("下载文件失败");
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("下载文件失败");
} finally {
try {
inputStream.close();
response.getOutputStream().close();
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("下载文件失败");
}
}