packagejavaRobotPainter;importjava.awt.*;importjava.awt.datatransfer.*;importjava.awt.event.*;importjava.awt.image.BufferedImage;importjava.io.*;importjava.util.*;importjavax.imageio.ImageIO;/** * When this class is instantiated a bot is created, that draws a specified picture in Microsoft Paint. * This program has only been tested on Windows Vista with MS Paint version 6.0. * <br /><br /> * NOTE: The delay between each operation and the time to start MS Paint may have to be adjusted. * The shortcut key to maximize the window, in {@code initMsPaint()}, may also have to be changed. * It works with the Norwegian version of Vista. * * @author teaprog * @version 1.0, 30/04/12 */publicclassJavaRobotPainter{/** The size of the screen. */privateDimensionscreenSize=Toolkit.getDefaultToolkit().getScreenSize();/** Where to start painting on the x-axis. */privatestaticfinalintSTART_POSITION_X=61;/** Where to start painting on the y-axis. */privatestaticfinalintSTART_POSITION_Y=94;/** The size of the rectangles being drawn. */privateintrectangleSize=5;/** The colors this bot has at its disposal. */privateArrayList<Color>availableColors=newArrayList<Color>();/** The position for each color. */privateHashMap<Color,Point>colorPosition=newHashMap<Color,Point>();/** The colors available. */privateenumColorNr{COLOR_ONE,COLOR_TWO};/** The current color selected. */privateColorNrcurrentColor=ColorNr.COLOR_ONE;/** The selected colors. (By default color one is black and color two is white) */privateColor[]selectedColors=newColor[]{newColor(0,0,0),newColor(255,255,255)};/** The image that is going to be drawn in MS Paint. */privateBufferedImageimage;/** The process of MS Paint. */privateProcessmsPaint;/** The robot that is going to draw the image. */privateRobotrobot;/** The delay between each bot operation. This may have to be adjusted for different computers. */privateintrobotDelay=1;/** The time that is required to start MS Paint. This may have to be adjusted for different computers. */privatelongtimeRequiredToStartMsPaint=1000;/** * Executes MS Paint and starts drawing. * * @throws AWTException * @throws IOException */publicJavaRobotPainter()throwsAWTException,IOException{image=ImageIO.read(newFile("img/image.jpg"));robot=newRobot();robot.setAutoDelay(robotDelay);initMsPaint();startPainting();}/** * Executes MS Paint, sets the attributes of the picture, initializes the available colors * and chooses a filled rectangle as drawing utility. * * @throws IOException * @throws InterruptedException */privatevoidinitMsPaint()throwsIOException{msPaint=Runtime.getRuntime().exec("mspaint.exe");// wait until mspaint.exe startslongtime=System.currentTimeMillis();while(System.currentTimeMillis()-time<timeRequiredToStartMsPaint);// maximize the window// NOTE: the shortcut may vary, depending on the language your windows version hasrobot.keyPress(KeyEvent.VK_ALT);robot.keyPress(KeyEvent.VK_SPACE);robot.keyPress(KeyEvent.VK_M);robot.keyRelease(KeyEvent.VK_M);robot.keyRelease(KeyEvent.VK_SPACE);robot.keyRelease(KeyEvent.VK_ALT);setAttributes(image.getWidth(),image.getHeight());initColors();chooseFilledRectangle();}/** * Sets the canvas size in MS Paint. * * @param width - The width of the image to be drawn. * @param height - The height of the image to be drawn. */privatevoidsetAttributes(intwidth,intheight){// if the width or height is too large then exit programif(width+START_POSITION_X>screenSize.width||height+START_POSITION_Y>screenSize.height){System.out.println("The width or height is too large!");msPaint.destroy();System.exit(0);}// open attributes windowrobot.keyPress(KeyEvent.VK_CONTROL);robot.keyPress(KeyEvent.VK_E);robot.keyRelease(KeyEvent.VK_E);robot.keyRelease(KeyEvent.VK_CONTROL);// set width and heightsetCliboard(newInteger(width).toString());pasteDataFromClipboard();robot.keyPress(KeyEvent.VK_TAB);robot.keyRelease(KeyEvent.VK_TAB);setCliboard(newInteger(height).toString());pasteDataFromClipboard();robot.keyPress(KeyEvent.VK_ENTER);robot.keyRelease(KeyEvent.VK_ENTER);}/** * Initializes the available colors. That is the 28 colors in the color panel above the canvas. */privatevoidinitColors(){intinterval=16;// The distance the mouse is going to be moved from each color.intstartX=95;// The x position to the first color in the panel.intstartY=55;// The y position to the first color in the panel.// Finds the colors and adds them to avaibleColors, and puts the color position in colorPosition.for(inti=0;i<14;i++){for(intj=0;j<2;j++){Colorcolor=robot.getPixelColor(startX+i*interval,startY+j*interval);availableColors.add(color);colorPosition.put(color,newPoint(startX+i*interval,startY+j*interval));}}}/** * Sets a filled rectangle as drawing tool. */privatevoidchooseFilledRectangle(){// choose rectanglerobot.mouseMove(15,210);robot.mousePress(InputEvent.BUTTON1_MASK);robot.mouseRelease(InputEvent.BUTTON1_MASK);// choose filledrobot.mouseMove(15,300);robot.mousePress(InputEvent.BUTTON1_MASK);robot.mouseRelease(InputEvent.BUTTON1_MASK);}/** * Presses the keys "Ctrl" and "V" to paste the content from the clipboard. */privatevoidpasteDataFromClipboard(){robot.keyPress(KeyEvent.VK_CONTROL);robot.keyPress(KeyEvent.VK_V);robot.keyRelease(KeyEvent.VK_V);robot.keyRelease(KeyEvent.VK_CONTROL);}/** * Sets the cliboard to the specified string. * * @param string - The string to be copied into clipboard. */publicvoidsetCliboard(Stringstring){Clipboardclipboard=Toolkit.getDefaultToolkit().getSystemClipboard();clipboard.setContents(newStringSelection(string),null);}/** * Starts painting the image in MS Paint. * If the user moves the mouse then the program terminates. */privatevoidstartPainting(){Pointpoint=newPoint(MouseInfo.getPointerInfo().getLocation().x,MouseInfo.getPointerInfo().getLocation().y);for(inti=START_POSITION_Y;i-START_POSITION_Y<image.getHeight();i+=rectangleSize){for(intj=START_POSITION_X;j-START_POSITION_X<image.getWidth();j+=rectangleSize){// if user moves the mouse then the program terminatesif(point.x!=MouseInfo.getPointerInfo().getLocation().x||point.y!=MouseInfo.getPointerInfo().getLocation().y)System.exit(0);setColor(newColor(image.getRGB(j-START_POSITION_X,i-START_POSITION_Y)));intmouseButton=(currentColor==ColorNr.COLOR_ONE)?InputEvent.BUTTON1_MASK:InputEvent.BUTTON3_MASK;robot.mouseMove(j,i);robot.mousePress(mouseButton);robot.mouseMove(j+rectangleSize,i+rectangleSize);robot.mouseRelease(mouseButton);// set the position of the last point where the mouse waspoint.setLocation(j+rectangleSize,i+rectangleSize);}}}/** * Changes the color if necessary, i.e. if the color is not in {@code selectedColors[0]} or {@code selectedColors[1]}. * * @param pixelColor - The pixel color, from the image, where the program has to find an approximated color in {@code availableColors}. */privatevoidsetColor(ColorpixelColor){ColormostAccurateColor=findMostAccurateColorAvailable(pixelColor);if(selectedColors[0].equals(mostAccurateColor)){currentColor=ColorNr.COLOR_ONE;}elseif(selectedColors[1].equals(mostAccurateColor)){currentColor=ColorNr.COLOR_TWO;}else{// If the color is not in selectedColors, then select new color from the panel.Pointp=colorPosition.get(mostAccurateColor);intmouseButton;if(currentColor==ColorNr.COLOR_ONE){mouseButton=InputEvent.BUTTON3_MASK;currentColor=ColorNr.COLOR_TWO;selectedColors[1]=mostAccurateColor;}else{mouseButton=InputEvent.BUTTON1_MASK;currentColor=ColorNr.COLOR_ONE;selectedColors[0]=mostAccurateColor;}robot.mouseMove(p.x,p.y);robot.mousePress(mouseButton);robot.mouseRelease(mouseButton);}}/** * Finds the most accurate color that is available in {@code availableColors}. * * @param pixelColor - The pixel color in the image. * @return the most accurate color from {@code availableColors} */privateColorfindMostAccurateColorAvailable(ColorpixelColor){doubleminError=Double.MAX_VALUE;intbestColorIndex=0;for(inti=0;i<availableColors.size();i++){intr1=availableColors.get(i).getRed();intg1=availableColors.get(i).getGreen();intb1=availableColors.get(i).getBlue();intr2=pixelColor.getRed();intg2=pixelColor.getGreen();intb2=pixelColor.getBlue();// 2-norm distancedoubleerror=Math.sqrt((r1-r2)*(r1-r2)+(g1-g2)*(g1-g2)+(b1-b2)*(b1-b2));if(error<minError){minError=error;bestColorIndex=i;}}returnavailableColors.get(bestColorIndex);}/** * The main method. * * @param args * @throws AWTException * @throws IOException * @throws InterruptedException */publicstaticvoidmain(String[]args)throwsAWTException,IOException{newJavaRobotPainter();}}