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

本文对比了使用connection和ImageIO方法读取网络图片的差异,指出ImageIO能有效解决图片抓取不完整的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
	}

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

 

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

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值