package servers;
import hypermedia.video.OpenCV;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.URL;
import java.sql.Connection;
import java.util.Arrays;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import processing.core.PApplet;
import processing.core.PImage;
import utils.ConsoleIO;
import com.sdicons.json.parser.JSONParser;
//import com.sun.tools.javac.tree.Tree.Try;
/**
*
* Esta clase se encarga de descargar las imagenes, guardarlas en disco, procesarlas para
* detectar los ojos.
*
* @author diex
*
*/
public class ImageSearcher implements ImageSearchClient {
public Logger logger = Logger.getLogger("Search Client");
///////////////////////////////////////////////////
// BUSQUEDA EN GOOGLE
///////////////////////////////////////////////////
private Google g;
private String query = null;
private int pagesLimit = 3;
private int currentPage = 0;
///////////////////////////////////////////////////
// ANALISIS DE IMAGEN : ROSTRO
///////////////////////////////////////////////////
FaceDetection fd;
ImageSearchListener parent;
public ImageSearcher(ImageSearchListener parent){
this.parent = parent;
// el buscador google recibe este objeto
// como referencia. Es este objeto quien recibe el callback
// desde el buscador una vez que encuentra los links a las imagenes
g = new Google(this);
// analiza las imagenes y guarda los archivos de analisis
fd = new FaceDetection();
}
/**
* El unico metodo publico. Es llamado para buscar que inicie una busqueda de imagenes
* @param query que buscar
*/
public void searchImagesFor(String query){
this.query = query;
new Google(this).search(4, this.query, currentPage);
}
/**
* Callback utilizado por Google que me envia un set de resultados.
*/
public synchronized void resultEvent(JSONObject results) {
//TODO solucionar esto para que siga buscando en todas
// las paginas cada vez que entra un set nuevo
int totalPages = 0;
JSONArray imageData = null;
JSONArray pagesData;
String queryData = null;
try {
// los resultados
imageData = results.getJSONObject("responseData").getJSONArray("results");
logger.info("Total Results: " + results.getJSONObject("responseData").getJSONObject("cursor").getString("estimatedResultCount"));
// las paginas de los resultados
pagesData = results.getJSONObject("responseData").getJSONObject("cursor").getJSONArray("pages");
queryData = results.getJSONArray("query").getString(0);
totalPages = pagesData.length();
logger.info( "Total Pages: " + Integer.toString(totalPages));
// creo el directorio donde voy a guardar los resultados de imagenes con
// sus respectivos analisis
new File("./imagenes/" + query).mkdir();
//////////////////////////////////////////////////////////
// tomo el recorset y comienzo a descargar las imagenes
//////////////////////////////////////////////////////////
URL imageUrl = null;
Image image = null;
BufferedImage bufferedImage = null;
String imageName = null;
String analysisName = null;
for(int i = 0 ; i < imageData.length() ; i ++ ){
try {
// para nombre de la imagen y archivo de analisis uso el ID de google
// le saco los dos puntos finales porque lo convierte a / y no me sirve despues porque no lo puedo leer.
imageName = imageData.getJSONObject(i).getString("imageId").split(":")[0] + ".jpg";
analysisName = imageData.getJSONObject(i).getString("imageId").split(":")[0] + ".ana";
logger.info( "Image Name: " + imageName + " for query: " + queryData);
// la url de la foto
imageUrl = new URL(imageData.getJSONObject(i).getString("unescapedUrl"));
logger.info( "Image URL: " + imageUrl.toString());
// TODO: reemplazar por las clases de Apache http client
bufferedImage = ImageIO.read(imageUrl);
int[] img = new int[bufferedImage.getWidth() * bufferedImage.getHeight()];
bufferedImage.getRGB(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), img, 0, 0);
PImage temp = new PImage(bufferedImage.getWidth(), bufferedImage.getHeight());
System.arraycopy(img, 0, temp.pixels, 0, img.length); //temp.pixels
// PImage temp = new PImage(bufferedImage);
//////////////////////////////////////////////////////////
// Analizo las imagenes
//////////////////////////////////////////////////////////
Rectangle[] faces = null ;
try {
// ANALISIS DE IMAGEN
logger.info("Searching eyes in: " + imageName);
// TODO: esto es una cagada... aca siempre tira una excepcion.
// implementar un wrapper de OpenCV serio
logger.info("IMAGE INFO: " + imageName + "SIZE: " + temp.width + " : " + temp.height);
logger.info("ANALIZING IMAGE");
faces = fd.analyze(temp);
//////////////////////////////////////////////////////////
// guardo las imagenes y los archivos de ananlisis
//////////////////////////////////////////////////////////
try {
// GUARDO LA IMAGEN
logger.info(">>> SAVING TO DISK: " + imageName);
File imagefile = new File("./imagenes/" + query + "/" + imageName);
logger.info("IMAGE INFO: " + imageName + "SIZE: " + temp.width + " : " + temp.height);
if(temp.width > 800 || temp.height > 600){
logger.info("IMAGE DISCARTED");
}else{
logger.info("ANALIZING IMAGE");
faces = fd.analyze(temp);
}
// GUARDO EL ANALISIS
logger.info("Saving Analisis file to disk");
File analysisFile = new File("./imagenes/" + query + "/" + analysisName);
FileWriter fw = new FileWriter(analysisFile);
if(faces.length > 0){
for(Rectangle r : faces ){
fw.write(r.toString() + "\n");
logger.info("rectangles for: " + imageName + " " + r.toString());
}
}else{
logger.info("rectangles for: " + imageName + " NOT FOUND " );
fw.write("none");
}
fw.close();
logger.info("Analisis saved OK");
} catch (IOException e) {
logger.warn("PROBLEM SAVING IMG/ANA");
e.printStackTrace();
System.out.println();
}
} catch (Exception e) {
logger.warn("PROBLEM PARSING IMAGE");
e.printStackTrace();
System.out.println();
}
} catch (Exception e) {
logger.warn("ERROR DOWNLOADING IMAGE: " + imageUrl.toString());
e.printStackTrace();
System.out.println();
}
} // FIN DEL FOR
} catch (Exception e) {
logger.warn( "ERROR GETTING GOOGLE DATA");
e.printStackTrace();
System.out.println();
}
// si hay mas resultados los sigo recuperando...
if(currentPage < totalPages - 1 && currentPage < pagesLimit){
currentPage++;
logger.info( "Current Index page: " + currentPage);
g.search(Google.SEARCH_IMAGE, query, currentPage);
}else{
System.out.println("SALIENDO DEL SEARCH");
parent.processFinishid("ENDSEARCH");
}
}
}