package com.xtremelabs.devicewall.programs.image; import java.awt.Dimension; import java.awt.image.BufferedImage; import java.io.Closeable; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageDecoder; import com.xtremelabs.devicewall.programs.amqp.AmqpConnectionManager; import com.xtremelabs.devicewall.programs.amqp.AmqpListener; import com.xtremelabs.devicewall.protocol.AmqpConstants; import com.xtremelabs.devicewall.protocol.Data; import com.xtremelabs.devicewall.protocol.Protocol; import com.xtremelabs.devicewall.protocol.gamecontrol.GameControlMessageType; import com.xtremelabs.devicewall.protocol.gamecontrol.request.ClientStartRequest; import com.xtremelabs.devicewall.protocol.gamecontrol.response.ServerStartResponse; import com.xtremelabs.devicewall.protocol.identifier.IdentifierMessageType; import com.xtremelabs.devicewall.protocol.identifier.data.MobileServerIdentifierData; import com.xtremelabs.devicewall.protocol.identifier.response.MapIdentifierResponse; import com.xtremelabs.devicewall.protocol.image.ImageDeserializer; import com.xtremelabs.devicewall.protocol.image.ImageMessageType; import com.xtremelabs.devicewall.protocol.image.request.ClientStartConfirmRequest; public class DeviceWallImageProgram { public static class PhoneInfo { public PhoneInfo(Long id, String queue, double xRelative, double yRelative, double widthRelative, double heightRelative) { this.id = id; this.queue = queue; this.xRelative = xRelative; this.yRelative = yRelative; this.widthRelative = widthRelative; this.heightRelative = heightRelative; } public Long id; public String queue; public double xRelative; public double yRelative; public double widthRelative; public double heightRelative; } public static class OCRResponse { public double width; public double height; public PhoneInfo[] screens; } private static AmqpConnectionManager mAmqpConnectionManager; private static Gson sGson; static { final GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(Protocol.class, new ImageDeserializer()); sGson = builder.create(); } private static String url; private static Dimension imageDimensions; private static Map<Long, PhoneInfo> map = new HashMap<Long, PhoneInfo>(); public static void main(final String[] args) throws Exception { mAmqpConnectionManager = new AmqpConnectionManager(sAmqpListener); } private static void sendStartMessage() { mAmqpConnectionManager.publishToAll(GameControlMessageType.SERVER_START.toString(), new ServerStartResponse(AmqpConstants.IMAGE_SERVER_APP_NAME).toJson().toString()); } private static void sendMessages(final PhoneInfo info) { int x = (int) (info.xRelative * imageDimensions.width); int y = (int) (info.yRelative * imageDimensions.height); int width = (int) (info.widthRelative * imageDimensions.width); int height = (int) (info.heightRelative * imageDimensions.height); String json = String.format("{\"image_url\": \"%s\",\"show_rect\": {\"x\": %d,\"y\": %d,\"width\": %d,\"height\": %d}}", url, x, y, width, height); System.out.println("queue: " + info.queue + ", json: " + json); if (info.id != null) { mAmqpConnectionManager.publishToBinding(Long.toString(info.id), "image", json); } else { mAmqpConnectionManager.publishToBinding(info.queue, "image", json); } } private static OCRResponse populateOCRMap() { // get info from OCR // String json = // "{\"width\": 2359.0, \"height\": 1576.0, \"screens\": [{\"id\": 13, \"xRelative\": 0.03815175922000848, \"yRelative\": 0.7436548223350253, \"widthRelative\": 0.3128444256040695, \"heightRelative\": 0.9873096446700508},{\"id\": 18, \"xRelative\": 0.7236116998728275, \"yRelative\": 0.6605329949238579, \"widthRelative\": 0.9957609156422212, \"heightRelative\": 0.9035532994923858},{\"id\": 12, \"xRelative\": 0.6265366680796948, \"yRelative\": 0.24048223350253808, \"widthRelative\": 0.8944467994913099, \"heightRelative\": 0.4733502538071066},{\"id\": 17, \"xRelative\": 0.003391267486222976, \"yRelative\": 0.05710659898477157, \"widthRelative\": 0.17125900805426028, \"heightRelative\": 0.4403553299492386},{\"id\": 11, \"xRelative\": 0.39084357778719797, \"yRelative\": 0.7493654822335025, \"widthRelative\": 0.662144976685036, \"heightRelative\": 0.9961928934010152},{\"id\": 16, \"xRelative\": 0.29122509537939806, \"yRelative\": 0.3730964467005076, \"widthRelative\": 0.5582874099194574, \"heightRelative\": 0.608502538071066},{\"id\": 15, \"xRelative\": 0.2560406952098347, \"yRelative\": 0.0, \"widthRelative\": 0.5218312844425604, \"heightRelative\": 0.23223350253807107},{\"id\": 14, \"xRelative\": 0.069520983467571, \"yRelative\": 0.5380710659898477, \"widthRelative\": 0.20983467571004663, \"heightRelative\": 0.6649746192893401}]}"; String json = "{\"width\": 2002.0, \"height\": 1253.0, \"screens\": [{\"id\": 14, \"xRelative\": 0.007992007992007992, \"yRelative\": 0.026336791699920193, \"widthRelative\": 0.3926073926073926, \"heightRelative\": 0.37988826815642457},{\"id\": 13, \"xRelative\": 0.0034965034965034965, \"yRelative\": 0.6296887470071828, \"widthRelative\": 0.39760239760239763, \"heightRelative\": 1.0},{\"id\": 0, \"xRelative\": 0.8296703296703297, \"yRelative\": 0.0, \"widthRelative\": 1.0, \"heightRelative\": 0.1524341580207502}]}"; File jsonFile = new File("/Users/devfloater56/Development/workspace/FindSquares/squares_data.json"); if (jsonFile.exists()) { FileReader fr = null; try { fr = new FileReader(jsonFile); OCRResponse response = sGson.fromJson(fr, OCRResponse.class); for (PhoneInfo phone : response.screens) { phone.widthRelative -= phone.xRelative; phone.heightRelative -= phone.yRelative; map.put(phone.id, phone); } return response; } catch (IOException e) { e.printStackTrace(); } finally { closeStreams(fr); } } return null; } private static void closeStreams(Closeable... streams) { for (Closeable closeable : streams) { try { if (closeable != null) { closeable.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private static Dimension getImageDimensions(String url) { HttpClient client = new DefaultHttpClient(); HttpGet get = new HttpGet(url); HttpResponse response; try { response = client.execute(get); InputStream stream = response.getEntity().getContent(); JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(stream); BufferedImage bufferedImage = decoder.decodeAsBufferedImage(); int height = bufferedImage.getHeight(); int width = bufferedImage.getWidth(); Dimension dimension = new Dimension(width, height); return dimension; } catch (Exception e) { e.printStackTrace(); } return null; } private static void parseServerIdentifierResponse(final MapIdentifierResponse data) { Collection<MobileServerIdentifierData> map2 = data.getMap(); for (MobileServerIdentifierData entry : map2) { PhoneInfo phoneInfo = map.get(entry.getId()); if (phoneInfo != null) { phoneInfo.queue = entry.getQueueName(); } } } private static void handleClientStart() { OCRResponse response = populateOCRMap(); url = "http://" + AmqpConstants.MOBILE_HOST + ":8080/test.jpg";// "http://timenerdworld.files.wordpress.com/2013/01/wpid-photo-jan-14-2013-1117-am.jpg"; imageDimensions = getImageDimensions(url); adjustImageDimensions(response); mAmqpConnectionManager.publishToServer(IdentifierMessageType.MAP_SERVER_REQUEST.toString(), ""); } private static void adjustImageDimensions(OCRResponse response) { double ocrRatio = response.width / response.height; double imageRatio = imageDimensions.getWidth() / imageDimensions.getHeight(); if (ocrRatio < imageRatio) { imageDimensions.width = (int) (imageDimensions.height * ocrRatio); } else if (ocrRatio > imageRatio) { imageDimensions.height = (int) (imageDimensions.width / ocrRatio); } } private static AmqpListener sAmqpListener = new AmqpListener() { @Override public void handleDelivery(String body) throws IOException { System.out.println("handleDeliver ImageProg: " + body); final Protocol protocol = sGson.fromJson(body, Protocol.class); if (protocol == null) return; final Data data = protocol.getData(); final String typeString = protocol.getType(); System.out.println("messageType: " + typeString); final GameControlMessageType gameType = GameControlMessageType.getModelType(typeString); if (gameType == GameControlMessageType.CLIENT_START) { final ClientStartRequest clientStartRequest = (ClientStartRequest) protocol.getData(); if (AmqpConstants.IMAGE_SERVER_APP_NAME.equals(clientStartRequest.getApp())) handleClientStart(); return; } final IdentifierMessageType identifierType = IdentifierMessageType.getModelType(typeString); if (identifierType == IdentifierMessageType.MAP_SERVER_RESPONSE) { parseServerIdentifierResponse((MapIdentifierResponse) data); sendStartMessage(); return; } final ImageMessageType imageMessageType = ImageMessageType.getModelType(typeString); System.out.println("imageMessageType: " + imageMessageType); if (imageMessageType == ImageMessageType.CONFIRM) { final ClientStartConfirmRequest clientStartRequest = (ClientStartConfirmRequest) protocol.getData(); final Long id = protocol.getId(); System.out.println("id: " + id); System.out.println("map: " + map); if (id == null) return; final PhoneInfo phoneInfo = map.get(id); if (phoneInfo == null) return; sendMessages(phoneInfo); return; } } @Override public void onConnected() { } @Override public void onDisconnected() { } }; }