自己玩的图片转表格源码
发表于:2017-06-28 09:46:01 分类:JAVA 阅读:890次
前些时间自己用swing+POI写的一个把图片按像素点转存到表格文件的小程序。只为好玩。。。
效果是这样的。
下面贴一下源代码
需要的jar包:
poi-3.11-20141221.jar
poi-ooxml-3.11-20141221.jar
poi-ooxml-schemas-3.11-20141221.jar
xmlbeans-2.6.0.jar
MainView.java
/* * 这是游戏窗体 */ package top.ersredma.imagetoexcle; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Scanner; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingWorker; import javax.swing.border.EmptyBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.Document; public class MainView extends JFrame implements ActionListener{ private JPanel jp1, jp2, jp5,jp6,jp_main; private JButton jb_img,jb_file,jb_start,jb_dismiss,jb_ch; private JTextField jtf_img,jtf_file,jtf_w,jtf_h; private JLabel jl_img, jl_file,jl_info; private JCheckBox jcb_2,jcb_56,jcb_max,jcb_user,jcb_sava,jcb_thread,jcb_option; private JCheckBox[] jcbs=new JCheckBox[4]; private ImgPanel imgp; private String outfilePath; private InitColorsWorker worker; private int tempW; private int tempH; private BufferedImage image; private ExcelUtil eu; public MainView() { initView(); } public void initOptions(){ //读取文件更改配置 try { File config=new File("config/op.conf"); //FileReader reader = new FileReader(config); Scanner sc=new Scanner(config); String line = sc.nextLine(); String[] ops = line.split(","); if("1".equals(ops[ops.length-1])){ jcb_2.setSelected("1".equals(ops[0])); if(jcb_2.isSelected()){ selectJCheckBox(jcb_2); } jcb_56.setSelected("1".equals(ops[1])); if(jcb_56.isSelected()){ selectJCheckBox(jcb_56); } jcb_max.setSelected("1".equals(ops[2])); if(jcb_max.isSelected()){ selectJCheckBox(jcb_max); } jcb_user.setSelected("1".equals(ops[3])); if(jcb_user.isSelected()){ selectJCheckBox(jcb_user); } jcb_thread.setSelected("1".equals(ops[4])); jcb_sava.setSelected("1".equals(ops[5])); jcb_option.setSelected("1".equals(ops[6])); } sc.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } int model=0; boolean openThread=false; if(jcb_max.isSelected()){ model=ExcelUtil.MODEL_FULLCOLORS; if(jcb_thread.isSelected()){ openThread=true; } }else if(jcb_2.isSelected()){ model=ExcelUtil.MODEL_2COLORS; }else if(jcb_56.isSelected()){ model=ExcelUtil.MODEL_64COLORS; }else if(jcb_user.isSelected()){ model=ExcelUtil.MODEL_USER; } eu=new ExcelUtil(model, this, openThread); } private class InitColorsWorker extends SwingWorker{ @Override protected Object doInBackground() throws Exception { eu.initColors(); return null; } } public void startWork(){ this.worker=new InitColorsWorker(); worker.execute(); } public void cancelWork(){ worker.cancel(true); worker=null; } public void setInfo(String info){ jl_info.setText("操作信息:"+info); } private void initView() { Font font = new Font("楷体", Font.BOLD, 26); Font font_info = new Font("楷体", Font.PLAIN, 16); Font font1 = new Font("宋体", Font.PLAIN, 12); GridLayout layout = new GridLayout(2,1); jp1 = new JPanel(layout); jp1.setBorder(new EmptyBorder(10, 20, 10, 20)); // 设置边距 jl_img =new JLabel("请选择图片路径:",JLabel.CENTER); jtf_img=new JTextField(); jtf_img.setEditable(false); jb_img=new JButton("选择文件..."); jb_img.addActionListener(this); //jl_img.setBounds(20, 40, 60, 30); jl_file=new JLabel("请选择导出路径:",JLabel.CENTER); //jl_file.setBounds(20, 70, 60, 30); jtf_file=new JTextField(); jtf_file.setEditable(false); jb_file=new JButton("保存路径..."); jb_file.addActionListener(this); jp1.add(jl_img); jp1.add(jtf_img); jp1.add(jb_img); jp1.add(jl_file); jp1.add(jtf_file); jp1.add(jb_file); // 下部 jp2 = new JPanel(new FlowLayout()); jp2.setPreferredSize(new Dimension(1060, 100)); jp2.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 20)); jl_info=new JLabel("操作信息:"); jl_info.setFont(font_info); jl_info.setForeground(Color.RED); jl_info.setPreferredSize(new Dimension(1060, 20)); jb_dismiss=new JButton("重新开始"); jb_dismiss.setFont(font); jb_dismiss.setPreferredSize(new Dimension(160, 50)); jb_dismiss.addActionListener(this); jb_start = new JButton("开始导出"); jb_start.setFont(font); jb_start.setPreferredSize(new Dimension(160, 50)); jb_start.addActionListener(this); jp2.add(jl_info); jp2.add(jb_dismiss); jp2.add(jb_start); /****************** 中部开始 ******************/ jp5 = new JPanel(null); jp5.setPreferredSize(new Dimension(200, 800)); jp5.setBorder(BorderFactory.createEmptyBorder(10, 50, 10, 10)); jp5.setBackground(new Color(140, 200, 150)); imgp = new ImgPanel(); //东部 jp_main =new JPanel(new GridLayout(23,1)); jp_main.setPreferredSize(new Dimension(160, 800)); jp_main.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20)); JLabel jl_menu=new JLabel(" 操作菜单"); jl_menu.setFont(new Font("华文行楷", Font.BOLD, 19)); jp_main.add(jl_menu); JLabel label1 = new JLabel("_________________"); jp_main.add(label1); JLabel jl_select=new JLabel("图像模式:"); jp_main.add(jl_select); //ButtonGroup bgroup=new ButtonGroup(); jcb_2=new JCheckBox("2色"); jcb_56=new JCheckBox("64色"); jcb_max=new JCheckBox("max色"); jcb_max.setSelected(true); jcb_max.setEnabled(false); jcb_user=new JCheckBox("自定义"); jcb_2.addActionListener(this); jcb_56.addActionListener(this); jcb_max.addActionListener(this); jcb_user.addActionListener(this); jcbs[0]=jcb_2; jcbs[1]=jcb_56; jcbs[2]=jcb_max; jcbs[3]=jcb_user; selectJCheckBox(jcb_max); //bgroup.add(jcb_2); //bgroup.add(jcb_56); //bgroup.add(jcb_max); //bgroup.add(jcb_user); jp_main.add(jcb_2); jp_main.add(jcb_56); jp_main.add(jcb_max); jp_main.add(jcb_user); JLabel label2 = new JLabel("_________________"); jp_main.add(label2); JLabel jl_setXY=new JLabel("输出尺寸(<1024):"); jp_main.add(jl_setXY); jtf_w=new JTextField("宽:"); jtf_w.addFocusListener(new FocusListener() { @Override public void focusLost(FocusEvent e) { if(tempW!=0){ String ws=jtf_w.getText(); try{ int w=Integer.parseInt(ws); if(w>1024||w<64){ jtf_w.setText(tempW+""); jtf_h.setText(tempH+""); setInfo("只接受64<=x<=1024的数字!已恢复原值!"); }else if(w!=tempW){ //修改了宽度 double sx = (double) w / tempW; if(sx<1){ int h=(int)(tempH*sx); if(h>1024||h<64){ jtf_w.setText(tempW+""); jtf_h.setText(tempH+""); setInfo("缩小后高不符合64<=h<=1024!已恢复原值!"); }else{ jtf_h.setText(h+""); } }else{ jtf_w.setText(tempW+""); jtf_h.setText(tempH+""); setInfo("放大无意义,已恢复原值!"); } } }catch(Exception ex){ jtf_w.setText(tempW+""); jtf_h.setText(tempH+""); setInfo("只接受<=1024的数字!已恢复原值!"); } } } @Override public void focusGained(FocusEvent e) { // TODO Auto-generated method stub } }); jp_main.add(jtf_w); jtf_h=new JTextField("高:"); jtf_h.addFocusListener(new FocusListener() { @Override public void focusLost(FocusEvent e) { if(tempH!=0){ System.out.println("h失去焦点!"); String hs=jtf_h.getText(); try{ int h=Integer.parseInt(hs); if(h>1024||h<64){ jtf_w.setText(tempW+""); jtf_h.setText(tempH+""); setInfo("只接受64<=x<=1024的数字!已恢复原值!"); }else if(h!=tempH){ //修改了宽度 double sy = (double) h / tempH; if(sy<1){ int w=(int)(tempW*sy); if(w>1024||w<64){ jtf_w.setText(tempW+""); jtf_h.setText(tempH+""); setInfo("缩小后宽不符合64<=w<=1024!已恢复原值!"); }else{ jtf_w.setText(w+""); setInfo("尺寸数据合法,请保存更改!"); } }else{ jtf_w.setText(tempW+""); jtf_h.setText(tempH+""); setInfo("放大无意义,已恢复原值!"); } } }catch(Exception ex){ jtf_w.setText(tempW+""); jtf_h.setText(tempH+""); setInfo("只接受<=1024的数字!已恢复原值!"); } } } @Override public void focusGained(FocusEvent e) { // TODO Auto-generated method stub } }); jp_main.add(jtf_h); jb_ch=new JButton("更改输出尺寸"); jb_ch.addActionListener(this); jp_main.add(jb_ch); JLabel label3 = new JLabel("_________________"); jp_main.add(label3); JLabel lab_option=new JLabel("参数设置:"); jp_main.add(lab_option); jcb_thread=new JCheckBox("启用多线程"); jcb_thread.setSelected(false); jp_main.add(jcb_thread); jcb_sava=new JCheckBox("保留色彩字符"); jcb_sava.setSelected(true); jp_main.add(jcb_sava); jcb_option=new JCheckBox("记住设置"); jp_main.add(jcb_option); JLabel label4 = new JLabel("_________________"); jp_main.add(label4); JLabel label5 = new JLabel(" "); jp_main.add(label5); JLabel label7 = new JLabel("©CopyRight 2017-"); label7.setFont(font1); jp_main.add(label7); JLabel label8 = new JLabel("telnet_armin@qq.com"); label8.setFont(font1); jp_main.add(label8); jp6=new JPanel(); /****************** 中部结束 ******************/ this.add(jp1, "North"); this.add(jp5, "Center"); this.add(jp2, "South"); this.add(jp_main,"East"); this.add(jp6,"West"); this.setTitle("十字绣图纸设计"); this.setSize(1100, 720); this.setResizable(false); //居中显示 Toolkit toolkit = Toolkit.getDefaultToolkit(); int x = (int)(toolkit.getScreenSize().getWidth()-this.getWidth())/2; int y = (int)(toolkit.getScreenSize().getHeight()-this.getHeight())/2; this.setLocation(x, y); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { try { File config=new File("config/op.conf"); FileWriter writer = new FileWriter(config); String line=new StringBuilder().append(jcb_2.isSelected()?1:0) .append(",") .append(jcb_56.isSelected()?1:0) .append(",") .append(jcb_max.isSelected()?1:0) .append(",") .append(jcb_user.isSelected()?1:0) .append(",") .append(jcb_thread.isSelected()?1:0) .append(",") .append(jcb_sava.isSelected()?1:0) .append(",") .append(jcb_option.isSelected()?1:0).toString(); writer.write(line); writer.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } public void windowClosed(WindowEvent e) { } }); } @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getSource()==jb_img) { JFileChooser jfc=new JFileChooser(); jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES ); jfc.showDialog(new JLabel(), "选择"); File file=jfc.getSelectedFile(); if(file!=null){ String s=file.getAbsolutePath(); String[] sp = s.split("\\."); if(file.isFile()&&".JPG.BMP.JPEG.PNG".contains(sp[sp.length-1].toUpperCase())){ jtf_img.setText(s); imgp.setImagePath(s); tempW=imgp.getImgWidth(); tempH=imgp.getImgHeight(); jtf_h.setText(imgp.getImgHeight()+""); jtf_w.setText(imgp.getImgWidth()+""); //imgp.paintComponent(this.getGraphics()); this.paint(this.getGraphics()); this.image=imgp.getImage(); setInfo("图片设置成功!"); } else{ jtf_img.setText("文件格式有误,只支持jpg,jpeg,bmp,png"); } } }else if(e.getSource()==jb_file) { JFileChooser jfc=new JFileChooser(); jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES ); jfc.showDialog(new JLabel(), "选择"); File file=jfc.getSelectedFile(); if(file!=null){ if(file.isFile()){ jtf_file.setText("请选择文件夹!"); }else{ jtf_file.setText(file.getAbsolutePath()); outfilePath=file.getAbsolutePath(); setInfo("输出路径设置成功!"); } } }else if(e.getSource()==jb_ch) { if(image!=null){ int w=Integer.parseInt(jtf_w.getText()); int h=Integer.parseInt(jtf_h.getText()); if(w!=tempW){ tempW=w; tempH=h; image = ImageUtils.thumb(image, tempW, tempH, true); setInfo("更改尺寸成功!可以导出了!"); } } }else if(e.getSource()==jb_dismiss) { jtf_img.setText(""); jtf_file.setText(""); jl_info.setText("操作信息"); outfilePath=null; imgp=new ImgPanel(); image=null; this.repaint(); }else if(e.getSource()==jb_start) { //进入转存操作 if(eu.isInnt()&&image!=null&&(tempH<=1024&&tempW<=1024)&&outfilePath!=null&&!outfilePath.equals("请选择文件夹!")){ if(jcb_max.isSelected()){ int[][][] rgbs= ImageUtils.getImageGRB(image); eu.writeToFile(rgbs, outfilePath,jcb_sava.isSelected()); }else if(jcb_2.isSelected()){ int[][][] rgbs= ImageUtils.getImageGRB(image); eu.writeToFile(rgbs, outfilePath,jcb_sava.isSelected()); }else if(jcb_56.isSelected()){ int[][][] rgbs= ImageUtils.getImageGRB(image); eu.writeToFile(rgbs, outfilePath,jcb_sava.isSelected()); }else if(jcb_user.isSelected()){ int[][][] rgbs= ImageUtils.getImageGRB(image); eu.writeToFile(rgbs, outfilePath,jcb_sava.isSelected()); } }else{ String info=""; if(!eu.isInnt()){ info=info+"请耐心等待初始化数据!"; } if(image==null){ info=info+"请选择图片!"; } if(outfilePath==null||outfilePath.equals("请选择文件夹!")){ info=info+"请选择输出路径!"; } if(tempH>1024||tempW>1024){ info=info+"图片宽高请不要超过1024!"; } setInfo(info); } } else if(e.getSource()==jcb_2) { selectJCheckBox(jcb_2); cancelWork(); eu=new ExcelUtil(ExcelUtil.MODEL_2COLORS, this, false); startWork(); }else if(e.getSource()==jcb_56) { selectJCheckBox(jcb_56); cancelWork(); eu=new ExcelUtil(ExcelUtil.MODEL_64COLORS, this, false); startWork(); }else if(e.getSource()==jcb_max) { //jcb_2.setEnabled(true); //jcb_56.setEnabled(true); //jcb_max.setEnabled(false); //jcb_user.setEnabled(true); selectJCheckBox(jcb_max); cancelWork(); eu=new ExcelUtil(ExcelUtil.MODEL_FULLCOLORS, this, jcb_thread.isSelected()); startWork(); }else if(e.getSource()==jcb_user) { //jcb_2.setEnabled(true); //jcb_56.setEnabled(true); //jcb_max.setEnabled(true); //jcb_user.setEnabled(false); selectJCheckBox(jcb_user); cancelWork(); eu=new ExcelUtil(ExcelUtil.MODEL_USER, this, false); startWork(); } } public void writeOver(String out){ jl_info.setText("操作信息:导出完成!"+out); } public static void main(String[] args) { MainView view = new MainView(); view.initOptions(); view.startWork(); } @Override public void paint(Graphics g) { // TODO Auto-generated method stub super.paint(g); imgp.paintComponent(this.getGraphics()); } private void selectJCheckBox(JCheckBox jcb){ for(JCheckBox jc :jcbs){ if(jc==jcb){ jc.setEnabled(false); }else{ jc.setSelected(false); jc.setEnabled(true); } } } }
关键词:java,poi,表格,图像
-
思路是把一张图每个点和rgb值读出来存入一个三维数组(长宽以及对应点的rgb值),然后新建一个工作表,按对应位置将表当前单元格的背景色设置为rgb的近似色——颜色信息量过大,处理的时候将每个色重新计算接近于系统生成的哪个色,实际写入的为系统色。