EV3のディスプレイに表示されている内容を画像ファイルに保存する

PCに接続したEV3のディスプレイに表示されている内容を画像ファイル(PNG)として保存します。

lejosについているEV3 Contorl Centerのコードを参考にしました。
lejosに含まれている、ev3classes.jar、ev3tools.jar をパスに加えてください。

![image50.png](https://qiita-image-store.s3.amazonaws.com/0/114629/a382a951-a647-5e01-8414-7790b531f074.png)


![image51.png](https://qiita-image-store.s3.amazonaws.com/0/114629/2c0e49e7-301a-5988-c1f9-e14492aa7a59.png) キャプチャした画像

# 使い方
起動したらターゲットとなるEV3のIPアドレスを入力して、[Conncet]ボタンをクリックして接続してください。接続されると、EV3の画面が表示されます。
[Capture]ボタンをクリックして、保存先ファイル名を入力してください。

USBでも、Bluetoothでも、接続する場合は、事前にEV3とPCを通信可能な状態にしておいてください。

```EV3Capture.java

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import lejos.ev3.tools.ConsoleViewComms;
import lejos.ev3.tools.ConsoleViewerUI;
import lejos.ev3.tools.LCDDisplay;


public class EV3Capture implements ConsoleViewerUI{
	private static final int LCD_WIDTH = 178;
    private static final int LCD_HEIGHT = 128;
    private static final Color COLOR_BACKGROUND = new Color(155, 205, 155, 255);
	
	private static final Dimension frameSize = new Dimension(800, 640);
	private static final Dimension menuPanelSize = new Dimension(800, 64);
	
	private JFrame frame = new JFrame("EV3 Capture");
	private JTextField nameText = new JTextField(8);
	private JButton connectButton = new JButton("Connect");
	private JButton captureButton = new JButton("Capture");
	
	private ConsoleViewComms cvc;
	private LCDDisplay lcd;
	private String directoryLastUsed;
	
    private BufferedImage image = new BufferedImage(LCD_WIDTH, LCD_HEIGHT, BufferedImage.TYPE_INT_ARGB);
    private Graphics2D imageGC = image.createGraphics();

    private boolean connected = false;
	

	public static void main(String args[]) {
		new EV3Capture().run();
	}
	
	private int run() {
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent w) {
				close();
				System.exit(0);
			}
		});
		cvc = new ConsoleViewComms(this, true);

		connectButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				if (!connected) {
					connect();
				} else {
					disconnect();
				}
			}
		});
		
		captureButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				caputre();
			}
		});
		
		createMenuPanel();
		createLCDPanel();

		frame.setPreferredSize(frameSize);
		frame.pack();
		frame.setVisible(true);
		return 0;
	}

	private void createMenuPanel() {
		JPanel menuPanel = new JPanel();
		frame.add(menuPanel, BorderLayout.NORTH);
		menuPanel.add(new JLabel("Name: "));
		menuPanel.add(nameText);
		menuPanel.add(connectButton);
		menuPanel.add(captureButton);
		menuPanel.setPreferredSize(menuPanelSize);
	}

	private void createLCDPanel() {
		lcd = new LCDDisplay();
		frame.add(lcd);
		lcd.clear();
		lcd.setMinimumSize(new Dimension(LCD_WIDTH, LCD_HEIGHT));
		lcd.setEnabled(true);
		lcd.setPreferredSize(lcd.getMinimumSize());
	}


	private String getSaveFilename() {
		JFileChooser filechooser = new JFileChooser(directoryLastUsed);
		int selected = filechooser.showSaveDialog(null);
		if (selected == JFileChooser.APPROVE_OPTION) {
			String filename = filechooser.getSelectedFile().getAbsolutePath();
			directoryLastUsed = filechooser.getSelectedFile().getParent();
			return filename;
		}
		return null;
	}
	
	private void close() {
		if (cvc != null) cvc.close();
	}

	private void updateConnectButton(boolean connected) {
		connectButton.setText((connected ? "Disconnect" : "Connect"));
	}

	private void connect() {
		String name = nameText.getText();
		
		if (name != null && name.length() > 0) {
			System.out.println("Connecting to " + name);
			try {
				cvc.connectTo(name, name, 0, true);
				connected = true;
				updateConnectButton(connected);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	private void disconnect() {
		close();
		connected = false;
		updateConnectButton(connected);
	}

	public void logMessage(String msg) {
		System.out.println(msg);
	}
	
	public void connectedTo(String name, String address) {
	}

	public void setStatus(String msg) {
		System.out.println("Status is " + msg);
	}

	public void append(String value) {
	}

    public void updateLCD(byte[] buffer) {
    	createImage(buffer);
    	lcd.update(buffer);
    }
    
    private void createImage(byte[] buffer) {
        imageGC.setColor(COLOR_BACKGROUND);
        imageGC.fillRect(0, 0, lcd.getWidth(), lcd.getHeight());
        imageGC.setColor(Color.BLACK);
        for(int y = 0;y<LCD_HEIGHT;y++) {
        	for(int x = 0; x<LCD_WIDTH;x++) {
        		int i = (y * (LCD_WIDTH/8 + 1) * 8) + x;
                int bit = (i & 0x7);
                int index = i / 8;
                int val =  ((buffer[index] >> bit) & 1);
        		if (val == 1) imageGC.fillRect(x, y, 1, 1);
        	}
        }
    }
    
    private void caputre() {
		String filename = getSaveFilename();
		if (filename == null) {
			return;
		}
		save(image, filename);
	}
    
    private void save(BufferedImage image, String filename) {
		try {
			OutputStream out = new FileOutputStream(filename);
			ImageIO.write(image, IMAGE_FILE_FORMAT, out);
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
    	
    }

}

```