经过了爬图,我得到了图片,以及图片的原网址,这个时候就该处理了。
图片处理本来是一件很复杂的事,而且各种特征也很多,而我仅仅是用的lire,别人第三方开源的jar包。
这里介绍下lire:Lucene Image REtrieval
lire是一个开源的基于图片内容的java类库,它提供了一种简单地方式来检索图像和照片,这是
基于图像的颜色和纹理特征来实现的。lire基于图像的内容和特点产生了一个lucene索引。
lire有多种不同的图像纹理的生成器,比如MPEG-7 ScalableColor, ColorLayout, and EdgeHistogram,
Auto Color Correlogram, PHOG, CEDD, JCD, FCTH等等。lire的搜图也是基于索引的,先把
一些图片读取,生成索引,然后在把待检索的图片来通过比对,从而得出相似的,并且有相似度
体现。lire源码是基于 Gnu GPL license.
而我呢,后台主要也是用到了lire的生成索引的技术。通过图片的object url,来获取图片
输入流,通过输入流一个个来添加索引。
下面给出加索引的主要代码:
public String craw() throws Exception {
keyvalue = URLDecoder.decode(keyvalue, "utf-8");
String url = new String();
url = crawUrl.getNextUrl(keyvalue);
System.out.println("2222");
List<String> urls = new ArrayList<String>();
List<String> infos = new ArrayList<String>();
List<String> homeUrls = new ArrayList<String>();
Connection connJsoup = Jsoup.connect(url.toString());
Document dochtml = connJsoup.timeout(20000).get();
String xml = dochtml.toString();
// 把xml拆开,然后提取目标url
urls = crawUrl.getObjInfo("\"pic_url\":\"", "\",", xml);
infos = crawUrl.getObjInfo("\"title\":\"", "\",", xml);
homeUrls = crawUrl.getObjInfo("\"page_url\":\"", "\",", xml);
// 得到索引存放地址
String location = ildi.getRootLocation().getValue();
// 创建一个合适的文件生成器,Lire针对图像的多种属性有不同的生成器
DocumentBuilder db = DocumentBuilderFactory.getJCDDocumentBuilder();
IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_33,
new SimpleAnalyzer(Version.LUCENE_33));
IndexWriter iw = new IndexWriter(FSDirectory.open(new File(location)),
iwc);
int num = 0;
// 建立索引,只建立前二十个
for (int i = 1; i < urls.size(); i++, num++) {
// 以下为建立索引的过程
java.net.URL myurl = new java.net.URL(urls.get(i));
java.net.HttpURLConnection conn = (java.net.HttpURLConnection) myurl
.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5 * 1000);
InputStream inStream;
try {
inStream = conn.getInputStream();// 通过输入流获取图片数据
} catch (Exception e) {
continue;
}
// 以下为插入图片过程
Picture picture = new Picture();
List<Integer> listKey = new ArrayList<Integer>();
int j = 0;
for (int k = 0; k < pdi.getAllPicture().size(); k++) {
listKey.add(pdi.getAllPicture().get(k).getId());
}
for (int k = 0; k < 1000000; k++) {
if (!listKey.contains(k)) {
j = k;
break;
}
}
picture.setId(j);
picture.setKeyWord(kwdi.getByValue(keyvalue));
picture.setName(urls.get(i));
picture.setDescription(infos.get(i));
picture.setObjurl(homeUrls.get(i));
if (num > 20) {
break;
}
pdi.addPicture(picture);
// 将图片存为doc
org.apache.lucene.document.Document doc = db.createDocument(
inStream, urls.get(i));
iw.addDocument(doc);
inStream.close();
}
// 将标记设为已建立索引
kwdi.updateIsAdd(keyvalue);
iw.optimize();
iw.close();
HttpServletResponse response = ServletActionContext.getResponse();
// 设置字符集
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.print("1");
return null;
}
由上面代码可以知道,lire在建立索引的时候,首先会创建一个合适的文件生成器documentbuilder。
DocumentBuilder db = DocumentBuilderFactory.getJCDDocumentBuilder();
然后再创建一个针对特定属性的索引写入类:
IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_33,
new SimpleAnalyzer(Version.LUCENE_33));
IndexWriter iw = new IndexWriter(FSDirectory.open(new File(location)),
iwc);
最后,将爬取到的每一份图片的输入流传给文件生成器db,db处理完后得到相应的索引,再有索引写入类
indexWriter写入到文件系统中。
如下图,已完成的索引文件