自己玩的图片转表格源码-查看文章

自己玩的图片转表格源码

发表于:2017-06-28 09:46:01 分类:JAVA 阅读:890次

image

前些时间自己用swing+POI写的一个把图片按像素点转存到表格文件的小程序。只为好玩。。。

效果是这样的。

2.png

下面贴一下源代码

需要的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,表格,图像


验证码:

  1. author
    灵智上人(伪装者) 2017-06-28 10:34:35
    思路是把一张图每个点和rgb值读出来存入一个三维数组(长宽以及对应点的rgb值),然后新建一个工作表,按对应位置将表当前单元格的背景色设置为rgb的近似色——颜色信息量过大,处理的时候将每个色重新计算接近于系统生成的哪个色,实际写入的为系统色。