diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..afdcaab --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +target/ +*.jar +*.class + +*.lst + +*.png \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..317e419 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "java.configuration.updateBuildConfiguration": "automatic", + "java.completion.filteredTypes": [ + "com.sun.*", + "sun.*", + "jdk.*", + "org.graalvm.*", + "io.micrometer.shaded.*" + ] +} \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e43cd5f --- /dev/null +++ b/pom.xml @@ -0,0 +1,70 @@ + + 4.0.0 + info.istlab.Zemi01 + Zemi01 + jar + 0.01 + Zemi01 + http://maven.apache.org + + + 11 + UTF-8 + UTF-8 + 11 + 11 + + + + + + junit + junit + 3.8.1 + test + + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.0.0 + + info.istlab.Zemi01.App + + + + + maven-assembly-plugin + + + + + + jar-with-dependencies + + ${project.artifactId}-${project.version}-exe + false + + + + info.istlab.Zemi01.App + + + all-permissions + . + + + + + + + + diff --git a/src/main/java/info/istlab/Zemi01/App.java b/src/main/java/info/istlab/Zemi01/App.java new file mode 100644 index 0000000..48da4e5 --- /dev/null +++ b/src/main/java/info/istlab/Zemi01/App.java @@ -0,0 +1,13 @@ +package info.istlab.Zemi01; + +/** + * Hello world! + * + */ +public class App +{ + public static void main( String[] args ) + { + System.out.println( "Hello World!" ); + } +} diff --git a/src/main/java/info/istlab/Zemi01/RectangleFrame.java b/src/main/java/info/istlab/Zemi01/RectangleFrame.java new file mode 100644 index 0000000..d70beec --- /dev/null +++ b/src/main/java/info/istlab/Zemi01/RectangleFrame.java @@ -0,0 +1,205 @@ +package info.istlab.Zemi01; + +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JWindow; +import javax.swing.SwingUtilities; + +// 中央が透明の、ドラッグで動かせるWindow群 +public class RectangleFrame implements MouseListener, MouseMotionListener { + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + RectangleFrame rf = new RectangleFrame(100, 100, 400, 300); + rf.setVisible(true); + + JPopupMenu menu = new JPopupMenu(); + menu.add("cancel"); + menu.addSeparator(); + JMenuItem captureMI = new JMenuItem("capture"); + captureMI.addActionListener(e -> ScreenCapture.capture(rf.getInnerRect(), System.getProperty("user.dir") )); + menu.add(captureMI); + JMenuItem exitMI = new JMenuItem("exit"); + exitMI.addActionListener(e -> System.exit(0)); + menu.add(exitMI); + + rf.registerPopupMenu(menu); + } + }); + } + + public void setVisible(boolean f) { + for (int i = 0; i < 4; i++) { + rects[i].setVisible(f); + } + } + + public void setBackground(Color c) { + for (int i = 0; i < 4; i++) { + rects[i].setBackground(c); + } + } + /** + * 内部サイズ + * @return + */ + public Dimension getInnerDim(){ + return new Dimension(width - frameWidth*2, height - frameWidth*2); + } + /** + * 内部矩形の左上の点 + * @return + */ + public Point getInnerPos(){ + return new Point(location.x + frameWidth, location.y + frameWidth); + } + /** + * 内部矩形 + * @return + */ + public Rectangle getInnerRect(){ + return new Rectangle( getInnerPos(), getInnerDim() ); + } + + TransparentRect[] rects = new TransparentRect[4]; + Point location; + int width, height, frameWidth; + + Point pressP; + Point pressWinP; // マウスプレスしたときの、RectangleFrameの位置 + boolean resizeMode = false; + Dimension dim; + JPopupMenu popupMenu; + + public RectangleFrame(int x, int y, int w, int h) { + location = new Point(x, y); + width = w; + height = h; + frameWidth = 10; + + for (int i = 0; i < 4; i++) { + rects[i] = new TransparentRect(this); + } + layout(); + } + + public void registerPopupMenu(JPopupMenu pM) { + popupMenu = pM; + } + + public void layout() { + rects[0].setLocation(location.x, location.y); + rects[0].setSize(width, frameWidth); + rects[1].setLocation(location.x, location.y + frameWidth); + rects[1].setSize(frameWidth, height - frameWidth * 2); + rects[2].setLocation(location.x + width - frameWidth, location.y + frameWidth); + rects[2].setSize(frameWidth, height - frameWidth * 2); + rects[3].setLocation(location.x, location.y + height - frameWidth); + rects[3].setSize(width, frameWidth); + for (int i = 0; i < 4; i++) + rects[i].toFront(); + } + + public void setLocation(int px, int py) { + location.setLocation(px, py); + layout(); + } + + public void setSize(int w, int h) { + width = w; + height = h; + layout(); + } + + @Override + public void mouseDragged(MouseEvent e) { + Point curP = e.getLocationOnScreen(); + int diffx = curP.x - pressP.x; + int diffy = curP.y - pressP.y; + // System.out.println(diffx+" "+diffy); + + if (resizeMode) { + if (dim.width + diffx > frameWidth*2 && dim.height + diffy > frameWidth*2){ + setSize(dim.width + diffx, dim.height + diffy); + } + } else { + setLocation(pressWinP.x + diffx, pressWinP.y + diffy); + } + } + + @Override + public void mouseMoved(MouseEvent e) { + if (e.getComponent() == rects[3] && + e.getPoint().x > rects[3].getWidth() - frameWidth) { + e.getComponent().setCursor(new Cursor(Cursor.SE_RESIZE_CURSOR)); + } else { + e.getComponent().setCursor(new Cursor(Cursor.MOVE_CURSOR)); + } + } + + @Override + public void mouseClicked(MouseEvent e) { + + } + + @Override + public void mousePressed(MouseEvent e) { + pressP = e.getLocationOnScreen(); + pressWinP = rects[0].getLocationOnScreen(); + resizeMode = false; + if (e.getButton() == MouseEvent.BUTTON3) { + if (popupMenu != null) { + popupMenu.show(e.getComponent(), e.getX(), e.getY()); + } // System.exit(0); + } + if (e.getComponent() == rects[3] && + e.getPoint().x > rects[3].getWidth() - frameWidth) { + resizeMode = true; + dim = new Dimension(width, height); + } + } + + @Override + public void mouseReleased(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseEntered(MouseEvent e) { + setBackground(new Color(0, 0, 0, 50)); + if (e.getComponent() == rects[3] && + e.getPoint().x > rects[3].getWidth() - frameWidth) { + rects[3].setCursor(new Cursor(Cursor.SE_RESIZE_CURSOR)); + } else { + e.getComponent().setCursor(new Cursor(Cursor.MOVE_CURSOR)); + } + + } + + @Override + public void mouseExited(MouseEvent e) { + setBackground(new Color(0, 0, 0, 10)); + e.getComponent().setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + } + +} + +class TransparentRect extends JWindow { + public TransparentRect(RectangleFrame parent) { + setBackground(new Color(0, 0, 0, 10)); + addMouseListener(parent); + addMouseMotionListener(parent); + } + +} diff --git a/src/main/java/info/istlab/Zemi01/ScreenCapture.java b/src/main/java/info/istlab/Zemi01/ScreenCapture.java new file mode 100644 index 0000000..a30a2e7 --- /dev/null +++ b/src/main/java/info/istlab/Zemi01/ScreenCapture.java @@ -0,0 +1,196 @@ +package info.istlab.Zemi01; + +import java.awt.Desktop; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +public class ScreenCapture { + public static void capture(Rectangle maybe, String dirPath) { + + File dir = new File(dirPath); + if (!dir.exists()) { + dir.mkdir(); + } + File file = FileUtil.createUniqueFile(dir, "capture.png"); + + try { + Robot robot = new Robot(); + // // メインウィンドウの右にあることを想定するため、メインウィンドウの位置とサイズを取得 + // Point pos = MainWindow.frame.getLocation(); + // Dimension dim = MainWindow.frame.getSize(); + // Rectangle maybe = new Rectangle(pos.x + dim.width, pos.y, 564, 322); + // System.out.println(maybe.toString()); + // Rectangle screenSize = new + // Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); + // Rectangle screenSize = new + // Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); + BufferedImage screenShot = robot.createScreenCapture(maybe); + ImageIO.write(screenShot, "png", file); + + // short[][][] brgb = bufferedImage2ByteArray(screenShot); + // replace(screenShot, brgb); // 水色を黒(0x030303)に変換 + // // うさこれエリアを探索(画像中心から、上下左右にボーダーを探索していく。) + // Rectangle area = getArea(screenShot); + // System.out.println(area.toString()); + // if (area.width == 480 && area.height == 240) { + // byte[][] map = bitmap2map(screenShot, area); + // MainWindow.app.mem.setAry(map); + // MainWindow.app.repaint(); + // } + + } catch (Exception e) { + System.out.println("キャプチャの取得に失敗しました。" + e.getMessage()); + } + System.out.println("画面キャプチャを取得しました。" + "\r\n" + file.getPath()); + try { + Desktop.getDesktop().open(file.getParentFile()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + // private static byte[][] bitmap2map(BufferedImage screenShot, Rectangle area) { + // int x = area.x; + // int y = area.y; + // byte[][] map = new byte[20][10]; + // // static Color[] cellColor = { Color.white, Color.cyan, Color.orange, + // // Color.green, Color.yellow, Color.MAGENTA }; + // // 代表色 ただし、0,255,0は無い。見つからなかったらGreen=3とする + // short[][] cellcolor = { { 180, 180, 180 }, { 1, 186, 255 }, { 255, 167, 0 }, { 0, 255, 0 }, { 255, 255, 0 }, + // { 255, 0, 41 } }; + // short[][][] brgb = bufferedImage2ByteArray(screenShot); + // for (int j = 0; j < 10; j++) { + // for (int i = 0; i < 20; i++) { + // int xx = x + i * 24; + // int yy = y + j * 24; + // // 探索する色を固定する + // boolean isFound = false; + // for (int itype = 0; itype < 6; itype++) { + // short[] findColor = cellcolor[itype]; + // for (int h = 0; h < 24; h++) { // xは xx+h y はyy+12 固定、横は1列のみチェックする。理由は耳の赤色をスキャンしないため。 + // if (diffsum(findColor, brgb[xx+h][yy+12]) < 30){ + // map[i][j] = (byte)itype; isFound = true; + // break; + // } + // } + // if (isFound){ + // break; + // } + // } + // if (!isFound) map[i][j] = 3; + // } + // } + // for (int j = 0; j < 10; j++) { + // for (int i = 0; i < 20; i++) { + // System.out.print(map[i][j] + " "); + // } + // System.out.println(""); + // } + // return map; + // } + public static int diffsum(short[] reference, short[] data){ + int diff = 0; + for(int i=0;i<3;i++){ + diff += Math.abs(data[i] - reference[i]); + } + return diff; + } + + public static Rectangle getArea(BufferedImage bi) { + int[] xywh = new int[4]; + int w = bi.getWidth(); + int h = bi.getHeight(); + // xywh[0] = xywh[2] = w/2; + // xywh[1] = xywh[3] = h/2; + + int[] searchX = { -1, 0, 1, 0 }; + int[] searchY = { 0, -1, 0, 1 }; + for (int i = 0; i < 4; i++) { + int[] xy = new int[2]; + xy[0] = w / 2; + xy[1] = h / 2; + while (true) { + System.out.println("search x " + xy[0] + " y " + xy[1] + " " + bi.getRGB(xy[0], xy[1])); + if (bi.getRGB(xy[0], xy[1]) == -16579837) { + xywh[i] = (i % 2 == 0) ? xy[0] : xy[1]; + System.out.println("i = " + i + " val = " + xywh[i] + " ============="); + break; + } + xy[0] += searchX[i]; + xy[1] += searchY[i]; + } + } + xywh[0]++; + xywh[1]++; + return new Rectangle(xywh[0], xywh[1], xywh[2] - xywh[0], xywh[3] - xywh[1]); + + } + + public static int[][] bufferedImage2IntArray(BufferedImage bi) { + int w = bi.getWidth(); + int h = bi.getHeight(); + int[][] ret = new int[w][h]; + for (int j = 0; j < h; j++) { + for (int i = 0; i < w; i++) { + ret[i][j] = bi.getRGB(i, j); + } + } + return ret; + } + + public static short[][][] bufferedImage2ByteArray(BufferedImage bi) { + int w = bi.getWidth(); + int h = bi.getHeight(); + short[][][] ret = new short[w][h][3]; + for (int j = 0; j < h; j++) { + for (int i = 0; i < w; i++) { + int pixel = bi.getRGB(i, j); + ret[i][j][0] = (short) (pixel >> 16 & 0xff); + ret[i][j][1] = (short) (pixel >> 8 & 0xff); + ret[i][j][2] = (short) (pixel & 0xff); + // System.out.println("r "+ret[i][j][0]+" g "+ret[i][j][1]+" b "+ret[i][j][2]); + } + } + return ret; + } + + public static void replace(BufferedImage bi, short[][][] brgb) { + int w = bi.getWidth(); + int h = bi.getHeight(); + for (int j = 0; j < h; j++) { + for (int i = 0; i < w; i++) { + if (Math.abs(brgb[i][j][0] - 148) < 30 && Math.abs(brgb[i][j][1] - 217) < 60 + && Math.abs(brgb[i][j][2] - 0xff) < 40) { + bi.setRGB(i, j, (3 << 16) + (3 << 8) + 3); + } + } + } + } +} + +class FileUtil { + public static File createUniqueFile(File directory, String fileName) { + String name; + String extention; + if (fileName.contains(".")) { + name = fileName.split("\\.")[0]; + extention = "." + fileName.split("\\.")[1]; + } else { + name = fileName; + extention = ""; + } + int counter = 0; + do { + String uniqueName = String.format("%s%03d%s", name, ++counter, extention); + File f = new File(directory, uniqueName); + if (!f.exists()) { + return f; + } + } while (true); + } +} diff --git a/src/test/java/info/istlab/Zemi01/AppTest.java b/src/test/java/info/istlab/Zemi01/AppTest.java new file mode 100644 index 0000000..389f7bb --- /dev/null +++ b/src/test/java/info/istlab/Zemi01/AppTest.java @@ -0,0 +1,38 @@ +package info.istlab.Zemi01; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +}