struts2+json+Lire制作以图搜图接口供php调用

背景:项目中需要开发以图搜图的功能,查找资料后发现开源框架Lire可以基本做到。悲剧的是Lire基于java应用,没有php接口可以调用,于是想以json+struts2开发个jee项目,做为php端的http请求接口来应用。

首先:下载Lire的demo文件(看源码是可以的,只是涉及到的算法,很多对于我这种理论知识特差的人来说,基本看不懂)

第二:找到demo的入口文件,然后新建一个web项目。将demo项目内java目录下所有的包文件拷入新建项目内的src目录下( net开头的包是Lire的,com的是测试包文件),另外将所有的jar包文件放入到项目中的WebContent/WEB-INF/lib目录下,最后开始配置struts2的相关内容(http://blog.csdn.net/cdy102688/article/details/9738717)

第三:将测试的java文件改为struts2的action对应类,在struts2的解压文件中找到json相关的jar包导入。并在struts.xml中设置json返回值对应的访问action(详细的配置后面给出)

配置后的struts.xml文件

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE struts PUBLIC  
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
    "http://struts.apache.org/dtds/struts-2.0.dtd">  
  
<struts>  
    <include file="struts-default.xml" />  
    <package name="default" namespace="/" extends="struts-default">  
        <action name="imageSearch" class="com.cdy.imagesearch.action.ImgSearchAction"
                method="imageSearch">  
            <result name="success">/index.jsp</result>
        </action>  
    </package>
    <package name="jsonInterface" extends="json-default">  
        <action name="imageSearchJson" class="com.cdy.imagesearch.action.ImgSearchAction" 
                method="imageSearchJson">  
            <result type="json">  
                <param name="root">responseJson</param>
            </result>
        </action>  
    </package>  
</struts>  
imageSearch:测试页面的action

imageSearchJson:返回json数据接口类型的action

转换后的ImgSearchAction文件(因为请求较少,业务处理不复杂。所以简略了封装前台数据的form层,业务处理的service层)

package com.eelly.imagesearch.action;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;

import net.semanticmetadata.lire.DocumentBuilder;
import net.semanticmetadata.lire.DocumentBuilderFactory;
import net.semanticmetadata.lire.ImageSearchHits;
import net.semanticmetadata.lire.ImageSearcher;
import net.semanticmetadata.lire.ImageSearcherFactory;

import org.apache.lucene.analysis.core.SimpleAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import com.eelly.imagesearch.beans.Goods;
import com.eelly.imagesearch.daoImpl.ImgSearchDaoImpl;
import com.opensymphony.xwork2.ActionSupport;

public class ImgSearchAction extends ActionSupport {
	private static final long serialVersionUID = 1L;
	
	// 索引文件存放路径
	private static String INDEX_PATH = "E:/index";
	
	// 要索引的图片文件目录
	private static String INDEX_FILE_PATH = "E:/image";
	
	// 请求的类型(1:页面测试,2:php接口调用)
	private int type=1;
	
	// 查找出的信息ID
	public String goods_id_str = "";
	
	// 用于搜索的图片
	private File imgFile;
	
	// 用于搜索的图片临时路径
	private String imgFileTmpUrl;
	
	// 定义接口返回时的json变量
	public Map responseJson; 
	
	public Map getResponseJson() {
		return responseJson;
	}

	public void setResponseJson(Map responseJson) {
		this.responseJson = responseJson;
	}

	public String getImgFileTmpUrl() {
		return imgFileTmpUrl;
	}

	public void setImgFileTmpUrl(String imgFileTmpUrl) {
		this.imgFileTmpUrl = imgFileTmpUrl;
	}

	public File getImgFile() {
		return imgFile;
	}

	public void setImgFile(File imgFile) {
		this.imgFile = imgFile;
	}
	
	public String getGoods_id_str() {
		return goods_id_str;
	}

	public void setGoods_id_str(String goods_id_str) {
		this.goods_id_str = goods_id_str;
	}

	/**
	 * 图片搜索(页面测入口)
	 */
	public String imageSearch() 
	{
		return this.deal_search();
	}
	
	/**
	 * 图片搜索(php接口入口)
	 */
	public String imageSearchJson() 
	{
		return this.deal_search();
	}
	
	/**
	 * 图片搜索处理
	 */
	public String deal_search()
	{
		if (imgFile == null)
		{
			if (imgFileTmpUrl != null && !"".equals(imgFileTmpUrl))
			{
				imgFile = new File(imgFileTmpUrl);
				type = 2;
			}
		}
		if (imgFile != null) 
		{
			ArrayList<Map<String, String>> goods_arr = new ArrayList<Map<String, String>>();
			Map<String, Object> goods_map = new HashMap<String, Object>();
			try {
				// 创建图片文件索引
				this.createIndex();
				// 打开索引
				IndexReader ir = IndexReader.open(FSDirectory.open(new File(INDEX_PATH)));
				// 创建一个图片搜索器
				ImageSearcher is = ImageSearcherFactory.createFCTHImageSearcher(ir.numDocs());
				//搜索图片源
				FileInputStream fis = new FileInputStream(imgFile);
				BufferedImage bi = ImageIO.read(fis);
				//根据上面提供的图片搜索相似的图片
				ImageSearchHits ish = is.search(bi, ir);
				
				//显示前匹配度在10以内(相似界限值)的记录(根据匹配度排序)
				for (int i = 0; i < ish.length(); i++) {
					if (ish.score(i) >= 0.0f && ish.score(i) <= 10.0f)
					{
						// 将查询到的相似的结果放入map,然后转换成json格式提供接口返回
						Map<String, String> goods = new HashMap<String, String>();
						goods.put("goods_id", ish.doc(i).getField("goods_id").stringValue());
						goods_arr.add(goods);
						goods_id_str += ish.doc(i).get(DocumentBuilder.FIELD_NAME_IDENTIFIER)+",";
					}
				}
				if (type == 2)
				{
					goods_map.put("total_count", goods_arr.size());
					goods_map.put("goods_info", goods_arr);
					this.setResponseJson(goods_map);
				}
				// 当查询完成后将用于搜索的文件删除
				imgFile.delete();
			} catch (Exception e) {
				System.out.println("图片搜索出现异常");
			}
		}
		return SUCCESS;
	}
	
	/**
	 * 创建图片库对应的lucence索引文件
	 * 可以做成定时任务
	 * @throws Exception
	 */
	public void createIndex() throws Exception 
	{
		//创建一个合适的文件生成器,Lire针对图像的多种属性有不同的生成器
		DocumentBuilder db = DocumentBuilderFactory.getFCTHDocumentBuilder();
		IndexWriterConfig iwc = new IndexWriterConfig(
				Version.LUCENE_42,new SimpleAnalyzer(Version.LUCENE_42));
		IndexWriter iw = new IndexWriter(FSDirectory.open(
				new File(INDEX_PATH)), iwc);
		iw.deleteAll();	//先清空所有的索引文件
		ImgSearchDaoImpl isd = new ImgSearchDaoImpl();
		// 获取数据库商品相关图片信息,作为创建图片库索引的源数据
		List<Goods> goods = isd.imgSearch();
		
		File parent = new File(INDEX_FILE_PATH);
		for (File f : parent.listFiles()) 
		{
			// 创建Lucene索引
			Document doc = db.createDocument(new FileInputStream(f),f.getName());
			
			// 添加索引字段
			String uri=f.getPath();
			@SuppressWarnings("deprecation")
			Field field=new Field("goods_id","1354985",Field.Store.YES,Field.Index.NO);
		    doc.add(field);
		    
			// 将文件加入索引
			iw.addDocument(doc);
		}
		iw.commit();
		iw.close();
	}
}
在创建图片索引的方法内涉及到读取数据库中存放的图片信息,所以会在后面将hibernate整合进来。整合了这两个后,会考虑将spring再放进来。目前的代码,正常流程测试是满足的,但毕竟是初版的代码,待改善的地方肯定很多(用到的时候,不妨多看看想想)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值