package metrobotics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.HeadlessException; import java.awt.Image; import java.awt.Toolkit; import java.awt.Transparency; import java.awt.color.ColorSpace; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.PixelGrabber; import java.awt.image.Raster; import java.awt.image.WritableRaster; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; import javaclient3.structures.PlayerConstants; import javaclient3.structures.PlayerMsgHdr; import javaclient3.structures.camera.PlayerCameraData; import javax.imageio.ImageIO; import javax.swing.ImageIcon; /** * @author Pablo Munoz - Metrobotics * This class is used when a Robot is using a Player CameraInterface. * The Thread will start every time a Robot is selected and it will die when * the user selects another robot. * */ public class CameraThread extends Thread { ArrayList<Robot> robots; Robot inUse; PlayerCameraData playerData; PlayerMsgHdr header; BufferedImage img; VisionDisplay vi; Image image; int indexRobot; CameraThread(Robot bot){// VisionDisplay vi){ //ArrayList<Robot> robots, BufferedImage img){ //robots = vi.robots; //img = vi.img; //this.vi = vi; header = new PlayerMsgHdr(); inUse = bot; //indexRobot = Robot.getRobotInUse(); } public void run(){ System.out.println("Thread for robot " + indexRobot + " started"); int imageCounter = 0; while(Robot.getCameraThread()){//Robot.visionThreadStarted){ //true) {//indexRobot == Robot.getRobotInUse()){ System.out.println("In VisionThread"); if(Robot.getRobotInUse()!=-1){ // System.out.println(Robot.getRobotInUse()); // inUse = robots.get(Robot.getRobotInUse()); //System.out.println("Robot vision in use: " + inUse.getName()); inUse.playerclient.readAll(); // I might not need this. header.setAddr(inUse.cam.getDeviceAddress()); header.setSeq(0); header.setSize(PlayerConstants.PLAYER_CAMERA_IMAGE_SIZE); header.setType(PlayerConstants.PLAYER_MSGTYPE_DATA); header.setTimestamp(inUse.cam.getTimestamp()); // THis should be changed header.setSubtype(PlayerConstants.PLAYER_CAMERA_CODE); inUse.cam.readData(header); //inUse.playerclient.readAll(); // I might not need this. //inUse.cam.readData(header); //playerData = inUse.cam.getData(); if(inUse.cam.isDataReady()){ //System.out.println("DataReady"); playerData = inUse.cam.getData(); //System.out.println("Bits per pixel: " + playerData.getBpp()); //System.out.println("Compression: " + playerData.getCompression()); //System.out.println("Fdiv: " + playerData.getFdiv()); //System.out.println("Format: " + playerData.getFormat()); //System.out.println("Height: " + playerData.getHeight()); //System.out.println("Width: " + playerData.getWidth()); //System.out.println("Image Count: " + playerData.getImage_count()); //System.out.println("Has code: " + playerData.hashCode()); //System.out.println("toString: " + playerData.toString()); // This could be done better by using byte [] imgBytes = playerData.getImage(); ByteBuffer bufimg = ByteBuffer.wrap(imgBytes); //System.out.println(bufimg.order()); bufimg.order(ByteOrder.LITTLE_ENDIAN); //System.out.println(bufimg.order()); bufimg.get(imgBytes); //System.out.println("Bytes new order: " + imgBytes); if(playerData.getCompression()==1){ image = Toolkit.getDefaultToolkit().createImage(imgBytes); image = new ImageIcon(image).getImage(); if(image==null){ System.out.println("Image is null"); } boolean hasAlpha = hasAlpha(image); //System.out.println("image has alpha: " + hasAlpha); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); try { // Determine the type of transparency of the new buffered image int transparency = Transparency.OPAQUE; if (hasAlpha) { transparency = Transparency.BITMASK; } // Create the buffered image GraphicsDevice gs = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gs.getDefaultConfiguration(); img = gc.createCompatibleImage( image.getWidth(null), image.getHeight(null), transparency); //image.getWidth(null), image.getHeight(null), transparency); //System.out.println("Creating image Width: " + image.getWidth(null) + " Height: " + image.getHeight(null)); } catch (HeadlessException e) { // The system does not have a screen } if (img == null) { // Create a buffered image using the default color model int type = BufferedImage.TYPE_INT_RGB; if (hasAlpha) { type = BufferedImage.TYPE_INT_ARGB; } //System.out.println("image to buffered Image"); img = new BufferedImage( image.getWidth(null), image.getHeight(null), type);// image.getWidth(null), image.getHeight(null), type); } // Copy image to buffered image //System.out.println("Image is not null"); Graphics2D g2 = img.createGraphics(); // Paint the image onto the buffered image // Graphics2D g2 = (Graphics2D)g; g2.drawImage(image, 0, 0, null); g2.dispose(); // File file = new File(inUse.getName() + "test.jpg"); // try { // ImageIO.write(img, "jpg", file); // } catch (IOException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } //vi.setImage(img); inUse.cameraImage = img; //vi.repaint(); //System.out.println("Vision Updated"); } else if(playerData.getCompression()==0){ // The Aibo image is raw image //System.out.println("Processing image without compression"); // Try1 // InputStream in = new ByteArrayInputStream(imgBytes); //try { // img = ImageIO.read(in); img = toImage(playerData.getWidth(), playerData.getHeight(), imgBytes); if(img == null){ //System.out.println("Image is NULL"); } else { File file = new File(inUse.getName() + imageCounter + "test.jpg"); try { ImageIO.write(img, "jpg", file); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } inUse.cameraImage = img; } //} catch (IOException e) { // TODO Auto-generated catch block //e.printStackTrace(); //} // try { // img = new BufferedImage( playerData.getWidth(), playerData.getHeight(), BufferedImage.TYPE_BYTE_BINARY); // img = ImageIO.read ( new ByteArrayInputStream ( imgBytes ) ); // // } catch (IOException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } //vi.setImage(img); } } } // else{ // //System.out.println("It could be that data is not ready"); // } // try { // Thread.sleep(30); // This sleep time should come also from the configuration file. // } catch (InterruptedException e) { // e.printStackTrace(); // return; // } } System.out.println("Thread ended for Robot " + indexRobot); return; } public static boolean hasAlpha(Image image) { // If buffered image, the color model is readily available if (image instanceof BufferedImage) { BufferedImage bimage = (BufferedImage)image; return bimage.getColorModel().hasAlpha(); } // Use a pixel grabber to retrieve the image's color model; // grabbing a single pixel is usually sufficient PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false); try { pg.grabPixels(); } catch (InterruptedException e) { } // Get the image's color model ColorModel cm = pg.getColorModel(); return cm.hasAlpha(); } public static BufferedImage toImage(int w, int h, byte[] data) { DataBuffer buffer = new DataBufferByte(data, w*h); int pixelStride = 3;// JP: it was 4; //assuming r, g, b, skip, r, g, b, skip... int scanlineStride = 3*w; // JP: it was 4*w //no extra padding int[] bandOffsets = {0, 1, 2}; //r, g, b WritableRaster raster = Raster.createInterleavedRaster(buffer, w, h, scanlineStride, pixelStride, bandOffsets, null); ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB); boolean hasAlpha = false; boolean isAlphaPremultiplied = false; int transparency = Transparency.OPAQUE; int transferType = DataBuffer.TYPE_BYTE; ColorModel colorModel = new ComponentColorModel(colorSpace, hasAlpha, isAlphaPremultiplied, transparency, transferType); return new BufferedImage(colorModel, raster, isAlphaPremultiplied, null); } public static BufferedImage toBufferedImage(Image image) { if (image instanceof BufferedImage) { return (BufferedImage)image; } // This code ensures that all the pixels in the image are loaded image = new ImageIcon(image).getImage(); // Determine if the image has transparent pixels; for this method's // implementation, see Determining If an Image Has Transparent Pixels boolean hasAlpha = hasAlpha(image); // Create a buffered image with a format that's compatible with the screen BufferedImage bimage = null; GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); try { // Determine the type of transparency of the new buffered image int transparency = Transparency.OPAQUE; if (hasAlpha) { transparency = Transparency.BITMASK; } // Create the buffered image GraphicsDevice gs = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gs.getDefaultConfiguration(); bimage = gc.createCompatibleImage( image.getWidth(null), image.getHeight(null), transparency); } catch (HeadlessException e) { // The system does not have a screen } if (bimage == null) { // Create a buffered image using the default color model int type = BufferedImage.TYPE_INT_RGB; if (hasAlpha) { type = BufferedImage.TYPE_INT_ARGB; } bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type); } // Copy image to buffered image Graphics g = bimage.createGraphics(); // Paint the image onto the buffered image g.drawImage(image, 0, 0, null); g.dispose(); return bimage; } }