如何用JAVA检测无效的图像URL(我的意思是图像没有被描述)?
我有一个从URL下载图像的方法。如下图所示如何用JAVA检测无效的图像URL(我的意思是图像没有被描述)?,java,image,Java,Image,我有一个从URL下载图像的方法。如下图所示 public static byte[] downloadImageFromURL(final String strUrl) { InputStream in; ByteArrayOutputStream out = new ByteArrayOutputStream(); try { URL url = new URL(strUrl); in = new BufferedInputStream(
public static byte[] downloadImageFromURL(final String strUrl) {
InputStream in;
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
URL url = new URL(strUrl);
in = new BufferedInputStream(url.openStream());
byte[] buf = new byte[2048];
int n = 0;
while (-1 != (n = in.read(buf))) {
out.write(buf, 0, n);
}
out.close();
in.close();
}
catch (IOException e) {
return null;
}
return out.toByteArray();
}
我有一个图像url,它是有效的。比如说
我的问题是,如果图像真的不存在,我不想下载。比如
我的方法不应下载此图像。那么,我怎么知道给出的图像URL不是真的存在呢。我不想验证我的URL(我认为这可能不是我的解决方案)
所以,我在谷歌上搜索了一下。从这篇文章。。。
和
但是这个con.getResponseCode()将始终返回状态代码“200”。这意味着我的方法还将下载无效的图像URL。所以,我将我的缓冲流输出为
System.out.println(in.read(buf));
无效的图像URL生成“43”。因此,我在我的方法中添加了这些代码行
if (in.read(buf) == 43) {
return null;
}
没关系。但我认为这并不总是令人满意的。还有别的办法吗?我说得对吗?如果有任何建议,我将不胜感激。这个问题可能会使我头疼。谢谢你阅读我的问题
*更新
我调用此下载方法并将下载的图像保存在某个目录中,如
// call method to save image
FileSupport.saveFile(filePath+".JPG", data);
之后,我试图输出为
File file = new File(filePath+".JPG);
System.err.println(file.length());
这也可能会为无效的图像URL生成“43”。我想知道为什么对所有无效URL返回“43”。什么是“43”?您可以添加第二个catch语句来捕获java.io.FileNotFoundException
catch (FileNotFoundException e) {
// Failed
}
我会这样做:
//By Nishanth Chandradas
import java.awt.Image;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.activation.MimetypesFileTypeMap;
import javax.swing.ImageIcon;
import java.io.File;
public class downloadimagefromurl {
/**
* @param args
* @throws IOException
*/
public static byte[] downloadImageFromURL(final String strUrl) throws IOException {
InputStream in;
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
URL url = new URL(strUrl);
in = new BufferedInputStream(url.openStream());
byte[] buf = new byte[2048];
int n = 0;
while (-1 != (n = in.read(buf))) {
out.write(buf, 0, n);
}
out.close();
in.close();
}
catch (IOException e) {
return null;
}
byte[] response = out.toByteArray();
FileOutputStream fos = new FileOutputStream("/Users/Nish/Desktop/image.jpg");
fos.write(response);
fos.close();
return response;
}
static boolean isImage(String image_path){
Image image = new ImageIcon(image_path).getImage();
if(image.getWidth(null) == -1){
return false;
}
else{
return true;
}
}
public static void main(String[] args) throws IOException {
downloadImageFromURL("https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcTxfYM-hnD-Z80tgWdIgQKchKe-MXVUfTpCw1R5KkfJlbRbgr3Zcg");
System.out.println(isImage("/Users/Nish/Desktop/image.jpg"));
}
根据下载是否为图像,输出将为真或假。如果
con.setRequestMethod(“HEAD”)代码>
如果图像不存在,则应该执行以下操作(从连接的输入中读取),否则将失败
HttpUrlConnection con = (HttpUrlConnection)url.openConnection;
con.setRequestMethod("GET");
con.addRequestProperty("User-Agent", "Mozilla/4.0");
int responseCode = con.getResponseCode(); //if you do not get 200 here, you can stop
if(responseCode != HttpUrlConnection.HTTP_OK) {
return;
}
// Now, read image buffer
byte[] image = null;
try{
InputStream in = new BufferedInputStream(con.getInputStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n = 0;
while (-1!=(n=in.read(buf)))
{
out.write(buf, 0, n);
}
out.close();
in.close();
image = out.toByteArray();
} catch (IOException ioe){
// do whatever you need
} finally {
con.disconnect();
}
还有,这个代码
if (in.read(buf) == 43) {
return null;
}
看起来不太好。一些神奇的数字,不清楚是什么。试试这个
在记事本或其他东西中打开图像,检查前3-4个字符,它将告诉您图像的格式
下载时,请检查前3或4个字符,这将告诉您此图像是否有效
注意:这里,我假设您的需求特定于某些类型的图像,而不是所有可能的图像
一些样本:
‰PNG图像的PNG
����JPG图像的JFIF
byte[] tenBytes=new byte[10];
// fill this array with the first 10 bytes.
String str = new String(tenBytes);
if(str.contains("JIFF")){
// JPG
}
if(str.contains("PNG"){
// PNG
} ...
如果没有匹配项,则可能是无效图像或您不想要的图像
注意:这是未经测试的代码。您可能需要对其进行调整才能正常工作。您应该将其视为psuedo代码来构建您的实现
更新:
您应该查找内容(如上所述),而不是检查文件大小43.如果不下载并查看图像,就无法检测到无效图像。@马特·鲍尔,你确定吗?有图像吗?你看到了吗?@akonsu,你的意思是我可以在下载后检测到吗?如果是,如何检测?你可以下载它,并检查其格式。我肯定有java库可以读取图像文件。如果读取失败,则是一个坏消息图像。@akonsu,谢谢你的建议,请指导我如何检查它的格式或者如何检查它是否是坏图像?我不这么认为,我已经这样测试过了。File File=new File(url);if(File.exists());@Nish Chandradas你的代码在某些情况下可能不正确(如果服务器需要用户代理)。你应该始终设置用户代理(如果您对服务器一无所知。如果您确实知道不需要用户代理,那么就可以了)在这种情况下,您也可以使用HttpUrlConnectionHttpUrlConnection con=(HttpUrlConnection)url.openConnection;con.addRequestProperty(“用户代理”,“Mozilla/4.0”);
我测试了你的代码,但是无效的url不会引发IOException。你确定吗?我没有发现无效图像的任何错误。当我添加它时,如果(in.read(buf)==43){return null;}在我的代码中。这可能会解决我的问题,但正如你所说,这看起来不太好,我不确定它是否总是令人满意。@Cataclysm你的URL是有效的,URL后面的图像是无效的。你的代码首先下载并保存,然后检查图像是否存在。我可以这样做。你的意思是需要下载,或者图像的URL是否有效?对于无效的url图像,image.getWidth(null)永远不会得到“-1”。正如您所说的“下载时检查前3或4个字符,这将告诉您此图像是否有效。”如何找到答案。我用一些psuedo代码更新了答案…这应该会有帮助。我感谢你的建议。我想知道,对于有效或无效的URL,这将是真正安全和确定的。根据你最初的问题,你想下载存在的图像。这意味着从包含图像的URL,我建议的方法ed正是这样做的。URL的有效性完全是另一回事。htt1p://www.some-site-that-doesnt-exist.com是一个无效的URL,因为协议错误,您共享的示例图像链接确实包含图像(尽管是1x1图像)。当您说有效/无效时,您是否担心图像的模糊?是的,我的意思是“无效”这个图片是不是真的不存在于互联网上。错误的文件名或被网站或上传者删除。但这并不意味着URL错误。我可以使用一些java方法支持的URLValidator。