我在比赛中主要负责的是用java语言进行识别平台界面的搭建以及与Python的连接,所以关于算法如何实现和图像如何处理在这里不做总结。界面的具体功能总结起来就是画板写数字,上传图片并显示。我们组做了两个界面,Swing界面和网页界面。下面分别地详细作结:
主界面设计
public class Interface extends JFrame {
private drawlistener dl;
private Graphics g;
JFrame frame=new JFrame();
public void Interface() {
frame.setTitle("手写数字识别"); //设置窗体名称
frame.setSize(600, 520); //设置窗体大小
frame.setDefaultCloseOperation(3); //用System exit 方法退出应用程序
frame.setLocationRelativeTo(null); //窗体居中
FlowLayout layout = new FlowLayout(FlowLayout.LEFT); //流式布局左对齐
frame.setLayout(layout); //窗体使用流式布局管理器
frame.setResizable(false); //窗体大小不变
更改鼠标样式
String url = "images/小手.png";
Toolkit tk = Toolkit.getDefaultToolkit();
Image image = new ImageIcon(url).getImage();
Cursor cursor = tk.createCustomCursor(image, new Point(10, 10), "norm");
frame.setCursor(cursor);
//使用数组保存按钮名
String buttonName[] = {"画笔","橡皮", "重置","图片","确定"};
//用于保存图形按钮,使用网格布局
JPanel jp1=new JPanel(new GridLayout(5, 2,20,20));
jp1.setPreferredSize(new Dimension(150, 400));
dl=new drawlistener(frame);
//循环为按钮面板添加按钮
for (int i = 0; i < buttonName.length; i++) {
JButton jbutton = new JButton(buttonName[i]);
jbutton.addActionListener(dl); //为按钮添加监听
jp1.add(jbutton);
}
JPanel jp2=new JPanel();//画布面板
jp2.setPreferredSize(new Dimension(420, 420));
jp2.setBackground(Color.WHITE);
// 定义Color数组,用来存储按钮上要显示的颜色信息
Color[] colorArray = { Color.BLUE, Color.GREEN, Color.RED,
Color.BLACK,Color.ORANGE,Color.PINK,Color.CYAN,
Color.MAGENTA,Color.DARK_GRAY,Color.GRAY,
Color.LIGHT_GRAY,Color.YELLOW};
//用于保存颜色按钮的面板
JPanel jp3=new JPanel(new GridLayout(1,colorArray.length,15,3));
// 循环遍历colorArray数组,根据数组中的元素来实例化按钮对象
for (int i = 0; i < colorArray.length; i++) {
JButton button = new JButton();
button.setBackground(colorArray[i]);
button.setPreferredSize(new Dimension(30, 30));
button.addActionListener(dl); //为按钮添加监听
jp3.add(button);
}
//将面板添加到主窗体
frame.add(jp1);
frame.add(jp2);
frame.add(jp3);
//添加按钮,作为当前颜色
JButton nowColor=new JButton();
nowColor.setPreferredSize(new Dimension(45,45));
nowColor.setBackground(Color.BLACK); //默认黑色
frame.add(nowColor);
//设置窗体的组件可见,如果为FALSE就看不到任何组件
frame.setVisible(true);
//获取画笔对象
g=jp2.getGraphics();
dl.setG(g);
dl.setNowColor(nowColor);
//为面板添加鼠标监听,用于绘制图形
jp2.addMouseListener(dl); //普通监听
jp2.addMouseMotionListener(dl); //拖动监听
}
处理鼠标监听
JFrame frame=new JFrame();
private Color color; //颜色属性
private Graphics g; //画笔属性
private String str; //保存按钮上的字符串,区分不同的按钮
private int x1,y1,x2,y2; //(x1,y1),(x2,y2)分别为鼠标的按下和释放时的坐标
private JButton nowColor; //当前颜色按钮
static private int i = 905;
private String dir = "group";
public drawlistener(JFrame frame) {
this.frame=frame;
}
//获取Draw类的画笔对象
public void setG(Graphics g) {
this.g = g;
}
//获取当前颜色按钮
public void setNowColor(JButton nowColor) {
this.nowColor = nowColor;
}
//鼠标拖动的方法
public void mouseDragged(MouseEvent e) {
//画线的方法
if ("画笔".equals(str)) {
int x, y;
x = e.getX();
y = e.getY();
float lineWidth = 20.0f;
((Graphics2D)g).setStroke(new BasicStroke(lineWidth));
g.drawLine(x, y, x1, y1);
x1 = x;
y1 = y;
}
if ("橡皮".equals(str)) {
int x, y;
x = e.getX();
y = e.getY();
float lineWidth = 30.0f;
((Graphics2D)g).setStroke(new BasicStroke(lineWidth));
g.setColor(color.WHITE);
g.drawLine(x, y, x1, y1);
x1 = x;
y1 = y;
}
}
//鼠标按下方法
public void mousePressed(MouseEvent e) {
g.setColor(color);//改变画笔的颜色
x1=e.getX();//获取按下时鼠标的x坐标
y1=e.getY();//获取按下时鼠标的y坐标
}
//鼠标释放方法
public void mouseReleased(MouseEvent e) {
x2=e.getX();//获取释放时鼠标的x坐标
y2=e.getY();//获取释放时鼠标的y坐标
}
//鼠标进入方法
public void mouseEntered(MouseEvent e) {
if ("画笔".equals(str)) {
String url = "images/画笔.png"; //储存鼠标图片的位置
Toolkit tk = Toolkit.getDefaultToolkit();
Image image = new ImageIcon(url).getImage();
Cursor cursor = tk.createCustomCursor(image, new Point(10, 10), "norm");
frame.setCursor(cursor);}
if ("橡皮".equals(str)) {
String url = "images/橡皮.png"; //储存鼠标图片的位置
Toolkit tk = Toolkit.getDefaultToolkit();
Image image = new ImageIcon(url).getImage();
Cursor cursor = tk.createCustomCursor(image, new Point(10, 10), "norm");
frame.setCursor(cursor);}
}
//鼠标退出方法
public void mouseExited(MouseEvent e) {
//设置鼠标样式
String url = "images/小手.png";
Toolkit tk = Toolkit.getDefaultToolkit();
Image image = new ImageIcon(url).getImage();
Cursor cursor = tk.createCustomCursor(image, new Point(10, 10), "norm");
frame.setCursor(cursor);
}
public void actionPerformed(ActionEvent e) {
//判断是颜色按钮还是图形按钮
if ("".equals(e.getActionCommand())) {
JButton jb = (JButton) e.getSource();
color = jb.getBackground();
nowColor.setBackground(color);//处理当前颜色
} else {
str = e.getActionCommand();
if ("重置".equals(str)) {
g.setColor(color.WHITE);
float lineWidth = 600.0f;
((Graphics2D)g).setStroke(new BasicStroke(lineWidth));
g.drawLine(0, 0, 420, 420);
}
if("确定".equals(str)) {
try {
saveFile();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if("图片".equals(str)) {
deleteDirectory(dir);
showPicture();
}
}
}
public void deleteDirectory(String dir) {
File dirFile = new File(dir);
// 删除文件夹中的所有文件包括子目录
File[] files = dirFile.listFiles();
for (int i = 0; i < files.length; i++) {
// 删除子文件
if (files[i].isFile()) {
deleteFile(files[i].getAbsolutePath());
}
// 删除子目录
else if (files[i].isDirectory()) {
deleteDirectory(files[i].getAbsolutePath());
}
}
}
public void deleteFile(String fileName) {
File file = new File(fileName);
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if (file.exists() && file.isFile()) {
file.delete();
}
}
try {
Robot robot = new Robot();
BufferedImage bi = robot.createScreenCapture(new Rectangle(823,293,420,420));
FileOutputStream out = new FileOutputStream("image\\image1.png");
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(bi);
} catch (AWTException e1) {
e1.printStackTrace();
}
chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("test"));
chooser.showOpenDialog(null);
String name = chooser.getSelectedFile().getPath();
copypicture(name);
public void copypicture(String oldpath) {
try {
File temp = new File(oldpath);
FileOutputStream output;
FileInputStream input = new FileInputStream(temp);
output = new FileOutputStream(newpath);
byte[] b = new byte[1024 * 5];
int len;
while ((len = input.read(b)) != -1) {
output.write(b, 0, len);
}
output.flush();
output.close();
input.close();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
Process proc = null;
try {
proc = Runtime.getRuntime().exec("python "+PY_URL);
proc.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
BufferedReader br;
String answer = null;
br = new BufferedReader(new FileReader(new File(DATA_SWAP)));
answer = br.readLine();
经过这次比赛,感觉收获了很多。不仅仅是代码学习上的收获,更是对自己心智的历练。有时候调bug真的需要花费很多的时间和精力,而且情绪也时常会面临崩溃的境地。只希望自己在后来的代码学习中能够保持平和的内心,一直坚持下去,学到更多的东西。