功能说明:
1 鼠标单击:选取裁剪区域
2 鼠标双击:选取裁剪区域,并把裁剪区域保存为文件,同时把区域中心点的坐标保存
3 打开图片:从某个文件夹打开图片并显示,同时把该目录的所有图片的路径载进来。这个功能主要是针对这么种情况,
假如处理某个文件夹的图片集,在某一张终止了或者暂停了,下一次要从这种图片开始。
4 保存坐标:把裁剪区域保存为文件,同时把区域中心点的坐标保存
5 打开目录:把该目录的所有图片的路径载进来。
6 下一张:展示下一张图片。
常见用法:
1 “打开目录”,这时会将目录图片载进来,并显示第一张,这是可以 “鼠标双击”,选取该张图片的裁剪区域,保存坐标和裁剪区域,并展示下一张。
2 假如用法1在某一张图片暂停了,比如关闭该程序。下次可以利用“打开图片”从某张图片开始,然后继续利用“鼠标双击”一张一张处理。
注:其实按钮“保存坐标”和“下一张”只是作为功能测试使用,实际操作可以用“鼠标双击”代替。
下面附上源代码:
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.awt.image.CropImageFilter; import java.awt.image.FilteredImageSource; import java.awt.image.ImageFilter; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Collections; import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.filechooser.FileNameExtensionFilter; public class PhotoFrame extends JFrame { private static final long serialVersionUID = -2216276219179107707L; private Container con; private MousePanel zPanel; private JScrollPane imgSp; private JPanel btnPanel; private String imageDir; private String currImg;//文件名,不包含目录 private int currIndex;//当前图片索引 ArrayList<String> imgList;//所有图片的绝对路径 public void writeCropImg() throws IOException { BufferedImage sourceImage = (BufferedImage) zPanel.getImg(); Image croppedImage; ImageFilter cropFilter; int x = zPanel.getPointX()-25; int y = zPanel.getPointY()-25; //四个参数分别为图像起点坐标和宽高,即CropImageFilter(int x,int y,int width,int height),详细情况请参考API //指定要裁剪的的文件的宽度和高度,以及起始坐标 cropFilter =new CropImageFilter(x,y,50,50); //生成图片 croppedImage= Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(sourceImage.getSource(),cropFilter)); //获取创建后的图片的高度 int h1=croppedImage.getHeight(null); int w1=croppedImage.getWidth(null); BufferedImage bi=new BufferedImage(w1,h1,BufferedImage.TYPE_INT_RGB); Graphics g=bi.getGraphics(); //在画图的时候可以设置背景色 g.drawImage(croppedImage,0,0,Color.white,null); String dir = imageDir+"_crops"; //创建文件输出流 FileOutputStream fos=new FileOutputStream(new File(dir+"/"+currImg)); //将创建的图片写入到输出流 ImageIO.write(bi, "png", fos); fos.close(); } private void showNext() { updateCurrName(); zPanel.setImagePath(imgList.get(currIndex)); currIndex++; } private void updateCurrName() { String path = imgList.get(currIndex); int index = path.lastIndexOf('/'); currImg = path.substring(index); } private class nextHandler implements ActionListener { @Override public void actionPerformed(ActionEvent e) { showNext(); } } private class openDirHandler implements ActionListener { @Override public void actionPerformed(ActionEvent e) { JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);//设置只能选择目录 int returnVal = chooser.showOpenDialog(null); if(returnVal == JFileChooser.APPROVE_OPTION) { imageDir =chooser.getSelectedFile().getPath(); imgList = FileTool.refreshFileList(imageDir); currIndex = 0; showNext(); //System.out.println ( "你选择的目录是:" + selectPath ); //你选择的目录是:/home/linger/imdata/collar } } } private void savePointAndImg() { try { String dir = imageDir+"_points"; int x = zPanel.getPointX(); int y = zPanel.getPointY(); //打开文件 File f=new File(dir+"/"); if(!f.exists()) { f.mkdir(); } f=new File(dir+"/"+currImg); if(!f.exists()) { f.createNewFile(); } FileOutputStream fos=new FileOutputStream(f); OutputStreamWriter osw=new OutputStreamWriter(fos,"UTF-8"); BufferedWriter bw=new BufferedWriter(osw); //写入文件 bw.write(x+","+y); //关闭文件 bw.close(); osw.close(); fos.close(); writeCropImg(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } private class savePointHandler implements ActionListener { @Override public void actionPerformed(ActionEvent e) { savePointAndImg(); } } private class openImageHandler implements ActionListener { public void actionPerformed(ActionEvent e) { JFileChooser chooser = new JFileChooser(); FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & PNG Images", "jpg", "png"); chooser.setFileFilter(filter); int returnVal = chooser.showOpenDialog(null); if(returnVal == JFileChooser.APPROVE_OPTION) { File file = chooser.getSelectedFile(); imageDir = file.getParent(); imgList = FileTool.refreshFileList(imageDir); currImg = file.getName();//文件名,不包含路径 // System.out.println(); String path = file.getAbsolutePath(); currIndex = imgList.indexOf(path); zPanel.setImagePath(path); currIndex++; //内部类访问外部类,可以直接访问的啊 } } } private PhotoFrame() { con = getContentPane(); con.setLayout(new GridLayout(2,2)); zPanel = new MousePanel(); //zPanel.setImagePath("/home/linger/17820d01");//绑定图片 //zPanel.setPreferredSize(new Dimension(zPanel.getImgWidth(), zPanel.getImgHeight())); imgSp = new JScrollPane(); imgSp.setPreferredSize(new Dimension(zPanel.getImgWidth(), zPanel.getImgHeight())); imgSp.setViewportView(zPanel); imgSp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); imgSp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); //con.add(imgSp, BorderLayout.CENTER); con.add(imgSp); btnPanel = new JPanel(); btnPanel.setLayout(new FlowLayout()); btnPanel.setSize(300,100); JButton button = new JButton("打开图片"); button.setSize(100, 50); btnPanel.add(button); button.addActionListener(new openImageHandler()); button = new JButton("保存坐标"); button.setSize(100, 50); btnPanel.add(button); button.addActionListener(new savePointHandler()); button = new JButton("打开目录"); button.setSize(100, 50); btnPanel.add(button); button.addActionListener(new openDirHandler()); button = new JButton("下一张"); button.setSize(100, 50); btnPanel.add(button); button.addActionListener(new nextHandler()); con.add(btnPanel); zPanel.addMouseListener(new MouseAdapter(){ public void mouseClicked(MouseEvent e) { if(e.getClickCount() == 2) { savePointAndImg(); showNext(); } } }); finalSetting(); } private void finalSetting() { setTitle("标注工具"); Toolkit kit = Toolkit.getDefaultToolkit(); Dimension screenSize = kit.getScreenSize(); int screenHeight = screenSize.height; int screenWidth = screenSize.width; int frameH = getHeight(); int frameW = getWidth(); setLocation((screenWidth - frameW) / 2 - 250, (screenHeight - frameH) / 2 - 250); setSize(800, 600); //setSize(zPanel.getImgWidth()+10, zPanel.getImgHeight()+10); //setPreferredSize(new Dimension(zPanel.getImgWidth()+100, zPanel.getImgHeight()+100)); //pack(); setVisible(true); setResizable(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { new PhotoFrame(); } }
import java.awt.Graphics; import java.awt.Image; import java.awt.image.ImageFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import javax.imageio.ImageIO; public class ImgPanel extends javax.swing.JPanel { private static final long serialVersionUID = 1L; private Image image; private int imgWidth; private int imgHeight; public Image getImg() { return image; } public int getImgWidth() { return imgWidth; } public void setImgWidth(int imgWidth) { this.imgWidth = imgWidth; } public int getImgHeight() { return imgHeight; } public void setImgHeight(int imgHeight) { this.imgHeight = imgHeight; } public ImgPanel() { } public void setImagePath(String imgPath) { // 该方法不推荐使用,该方法是懒加载,图像并不加载到内存,当拿图像的宽和高时会返回-1; // image = Toolkit.getDefaultToolkit().getImage(imgPath); try { // 该方法会将图像加载到内存,从而拿到图像的详细信息。 image = ImageIO.read(new FileInputStream(imgPath)); //读取图片的大小 setImgWidth(image.getWidth(this)); setImgHeight(image.getHeight(this)); this.repaint(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } @Override public void paintComponent(Graphics g1) { super.paintComponent(g1); int x = 0; int y = 0; Graphics g = (Graphics) g1; if (null == image) { return; } g.drawImage(image, x, y, image.getWidth(this), image.getHeight(this), this); g = null; } }
import java.awt.*; import javax.swing.*; import java.awt.event.*; public class MousePanel extends ImgPanel//JPanel { int x_pos,y_pos; public int getPointX() { return x_pos; } public int getPointY() { return y_pos; } public MousePanel() { addMouseListener(new MouseListener() { //mouseClicked():鼠标单击 public void mouseClicked(MouseEvent e) { x_pos=e.getX(); y_pos=e.getY(); repaint(); } //mouseEntered():鼠标进入时 public void mouseEntered(MouseEvent e) { } //mouseExited():鼠标离开时 public void mouseExited(MouseEvent e) { } //mousePressed():鼠标按下去 public void mousePressed(MouseEvent e) { } //mouseReleased():鼠标松开时 public void mouseReleased(MouseEvent e) {} }); addMouseMotionListener(new MouseMotionListener() { public void mouseMoved(MouseEvent e) { } public void mouseDragged(MouseEvent e){} }); } public void paintComponent(Graphics g) { super.paintComponent(g); //g.drawString("current location is:["+x_pos+","+y_pos+"]",x_pos,y_pos);//在界面上显示 //System.out.printf("current location is:["+x_pos+","+y_pos+"]\n",x_pos,y_pos);//在控制台显示 g.setColor(Color.RED); g.drawRect(x_pos-25, y_pos-25, 50, 50); //g.fillOval(x_pos,y_pos,8,8); } }
import java.io.File; import java.util.ArrayList; public class FileTool { public static ArrayList<String> refreshFileList(String strPath) { ArrayList<String> filelist = new ArrayList<String>(); File dir = new File(strPath); File[] files = dir.listFiles(); if (files == null) { return filelist; } for (int i = 0; i < files.length; i++) { if (files[i].isDirectory()) { refreshFileList(files[i].getAbsolutePath()); } else { String strFileName = files[i].getAbsolutePath().toLowerCase(); //System.out.println(strFileName); filelist.add(files[i].getAbsolutePath()); } } return filelist; } public static void main(String[] args) { // TODO Auto-generated method stub ArrayList<String> test = refreshFileList("/home/linger/imdata/collar"); System.out.println(test.get(668)); System.out.println(test.get(669)); System.out.println(test.get(670)); } }