欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

记录一个读取网络图片的坑

程序员文章站 2022-05-16 11:23:13
...

Java读取网络图片有几种方式,目前使用比较多的是

1、使用connection模拟浏览器http请求的方式

2、直接使用ImageIO提供的方法

 

项目中有读取网络图片,并且输出图片base64后字符串给前端的需求。

开始是使用的是connection的方式,代码片段如下

public String getImage(String urlStr) throws IOException {

		URL url = new URL(urlStr);

		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setRequestMethod("GET");
		conn.setConnectTimeout(5 * 1000);
		conn.setReadTimeout(10000);
		conn.setRequestProperty("Referer", urlStr + "getYZM");
		conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
		conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");

		InputStream inStream = conn.getInputStream();
		byte[] data = new byte[inStream.available()];
		inStream.read(data);

		BASE64Encoder encoder = new BASE64Encoder();
		// 返回Base64编码过的字节数组字符串
		String base64Str = encoder.encode(data);

		inStream.close();
		return base64Str;
	}

问题:如上代码在执行的过程中,发现返回的图片经常是不完整的。

踩坑过程:

1、网上有部分网友提出可以使用getContentLength判断是否获取完整,但是由于是抓取网络的图片,也不能要求服务端设置contentLength。所以这个值获取到的是-1,不起作用。

2、设置更长的connectTimeout和readTimeout这个基本也不起作用

3、设置doInput和doOutput为true。其实doInput默认就是为true,也不起作用。

最后总结就是这个方法对于图片抓取不完整这个问题是走不通的。

 

然后使用ImageIO的方法,代码片段如下:

public String getImage(String urlStr) throws IOException {

		URL url = new URL(urlStr);
		BufferedImage image = ImageIO.read(url);
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		ImageIO.write(image, "jpg", out);
		byte[] data = out.toByteArray();
		// 对字节数组Base64编码
		BASE64Encoder encoder = new BASE64Encoder();
		// 返回Base64编码过的字节数组字符串
		String base64Str = encoder.encode(data);

		return base64Str;
	}

以上简短的代码就可以完美的解决了抓取图片不完整的问题了。。

 

这里只是描述了两种方式获取网络图片的差异,具体源码层面的不同就没有深入了解,这个还有待后续努力。

有描述不对的,欢迎大神拍砖。

相关标签: java网络