最近のプロジェクトは開料図と開版図を描きます

22322 ワード


 package org.javafans.print.common;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import javax.imageio.ImageIO;
import org.nutz.log.Logs;


public class DrawKL {
	
	public static void main(String[] args) throws Exception {
		getInstanse().CreateSegmentationMap(
				new Rectangle2D.Float(0F,0F, 990.0F, 800.0F),
				new Rectangle2D.Float(0f,0F, 200.0F,  400.0F), 3, new File("d:/1/real.jpg"), false);
	}
	
	/**
	 * @author tangsu
	 * @param outside       
	 * @param inside       
	 * @param type       2    3         
	 * @param tofile         
	 * @param isbook       true  
	 * @return   HspaiResult              outside         inside          null
	 */
	public HspaiResult CreateSegmentationMap(Rectangle2D r_outside, Rectangle2D r_inside, int type, File tofile, boolean isbook){
		Rectangle2D outside = new Rectangle2D.Double(r_outside.getX(), r_outside.getY(), r_outside.getWidth(), r_outside.getHeight());
		Rectangle2D inside = new Rectangle2D.Double(r_inside.getX(), r_inside.getY(), r_inside.getWidth(), r_inside.getHeight());
		double a_w = outside.getWidth();
		double a_h = outside.getHeight();
		double b_w = inside.getWidth();
		double b_h = inside.getHeight();
		double d_temp = 0d;
		if(a_w < a_h){
		    d_temp = a_w;   
		    a_w = a_h;
		    a_h = d_temp;
		    outside.setRect(0d, 0d, a_w, a_h);
		}
		if(b_w < b_h){
			d_temp = b_w;
		    b_w = b_h;
		    b_h = d_temp;
		    inside.setRect(0d, 0d, b_w, b_h);
		}
		
		if(a_w < b_w){//               null
			return null;
		}
		this.isbook = isbook;
		resultoutfile = tofile;
		if(!resultoutfile.getParentFile().exists()){
            resultoutfile.getParentFile().mkdirs();
        }
		if(isbook){
			xuxianbs = new BasicStroke(LINEPX / 2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10F, 
					new float[]{2, 2f, 4f, 2f, 2f, 2f}, 0F);
			xxline = new Line2D.Double();
		}
		try {
			HspaiResult resu = null;
			if(type == 2){
				resu = StartDrew(CreateTransverse(outside, inside), outside, inside);
			}else if(type == 3){
				resu = CreateAnyway(outside, inside, false);// true               false    
			}else{
				resu = StartDrew(CreateVertical(outside, inside), outside, inside);
			}
			if(resu == null){
				return null;
			}
			resu.outside = r_outside;
			resu.inside = r_inside;
			resu.clxl = getClxl(resu);
			return resu;
		} catch (Exception e) {
			Logs.getLog(DrawKL.class).error(e);
			return null;
		}
	}
	

	//                  
	private HspaiResult StartDrew(HspaiResult result, Rectangle2D outside, Rectangle2D inside) throws Exception{
		Rectangle2D huabu = getBigRect(outside, inside);
		BufferedImage img = new BufferedImage((int)huabu.getWidth(), (int)huabu.getHeight(), BufferedImage.TYPE_INT_RGB);
		Graphics2D g2 = (Graphics2D)img.getGraphics();
		BasicStroke basic = new BasicStroke(LINEPX);
		g2.setStroke(basic);
		g2.setColor(Color.WHITE);
		g2.setBackground(Color.WHITE);
		g2.fill(huabu);
		g2.setColor(Color.RED);
		huabu.setRect(0, 0, huabu.getWidth() - LINEPX, huabu.getHeight() - LINEPX);
		g2.draw(huabu);
		g2.setColor(Color.BLACK);
		for(int i = 1; i <= result.description.size(); i++){
			for(Rectangle2D r : result.description.get(i)){
				if(isbook){
					drawXXLine(g2, r, xxline, xuxianbs, basic);
				}
				g2.draw(r);
			}
		}
		ImageIO.write(img, "JPEG", new FileOutputStream(resultoutfile));
		return result;
	}
	
	//       
	private HspaiResult CreateTransverse(Rectangle2D outside, Rectangle2D inside) throws Exception{
		double dw = outside.getWidth() / inside.getWidth();
		int wn = (int) dw;
		double dh = outside.getHeight() / inside.getHeight();
		int hn = (int) dh;
		if(outside.getWidth() < outside.getHeight()){
			outside.setRect(0, 0, outside.getHeight(), outside.getWidth());
		}
		double f_y_t = 0d;
		double f_x_t = 0d;
		int row = 0;
		List<Rectangle2D> dep_arl = new LinkedList<Rectangle2D>();
		HashMap<Integer, List<Rectangle2D>> description = new HashMap<Integer, List<Rectangle2D>>();
		description.put(++row, dep_arl);
		HspaiResult re_temp = new HspaiResult();
		re_temp.description = description;
		for(int i = 0; i <= hn; i++){
			if(outside.getHeight() - f_y_t < inside.getHeight()){
				break;
			}
			f_x_t = 0d;
			for(int j = 0; j <= wn; j++){
				if(outside.getWidth() - f_x_t < inside.getWidth()){
					break;
				}
				inside.setRect(f_x_t , f_y_t, inside.getWidth(), inside.getHeight());
				dep_arl.add(new Rectangle2D.Double(inside.getX(), inside.getY(), inside.getWidth(), inside.getHeight()));
				++ re_temp.total;
				f_x_t += inside.getWidth();
			}
			f_y_t += inside.getHeight();
			dep_arl = new LinkedList<Rectangle2D>();
			description.put(++row, dep_arl);
		}
		return re_temp;
	}
	
	//       
	private HspaiResult CreateVertical(Rectangle2D outside, Rectangle2D inside) throws Exception{
		inside.setRect(inside.getX(), inside.getY(), inside.getHeight(), inside.getWidth());
		return CreateTransverse(outside, inside);
	}
	
	//        
	private HspaiResult CreateAnyway(Rectangle2D outside, Rectangle2D inside, boolean debug) throws Exception{
		//    
		HspaiResult hzfimg = CreateTransverse(outside, inside);
		int hp_total = hzfimg.total;
		//    
		HspaiResult szfimg = CreateVertical(outside, inside);
		int sp_total = szfimg.total;
		//  
		int hsp_total = getMaxiMum(outside, inside);
		
		if(debug){
			hp_total = 0;
			sp_total = 0;
		}
		
		if(hp_total >= sp_total && hp_total >= hsp_total){//    
			return StartDrew(hzfimg,outside, inside);
		}else if(sp_total >= hp_total && sp_total >= hsp_total){//    
			return StartDrew(szfimg,outside, inside);
		}else{//      
			Rectangle2D huabu = null;
			if(maxresult.description.size() > 0){
				List<Rectangle2D> frow = maxresult.description.get(1);
				double huabu_w = outside.getWidth() + ((frow.size() + 1) * LINEPX);
				double huabu_h = outside.getHeight() + ((maxresult.description.size() + 1) * LINEPX);
				outside.setRect(0, 0, huabu_w, huabu_h);
				huabu = outside;
			}else{
				huabu = getBigRect(outside, inside);
			}
			BufferedImage img = new BufferedImage((int)huabu.getWidth(), (int)huabu.getHeight(), BufferedImage.TYPE_INT_RGB);
			Graphics2D g2 = (Graphics2D)img.getGraphics();
			g2.setStroke(new BasicStroke(LINEPX));
			g2.setColor(Color.WHITE);
			g2.setBackground(Color.WHITE);
			g2.fill(huabu);
			g2.setColor(Color.RED);
			outside.setRect(0, 0, outside.getWidth() - LINEPX, outside.getHeight() - LINEPX);
			g2.draw(huabu);
			g2.setColor(Color.BLACK);
			BasicStroke bases = new BasicStroke(LINEPX);
//--------------------------------      -------      debug = false ------------------------------------------
			int iname = 0;
			if(debug){
					for(HspaiResult hs_resu_te : relist){
						iname++;
						for(int i = 1; i <= maxresult.description.size(); i++){
							for(Rectangle2D r : maxresult.description.get(i)){
								if(isbook){
									drawXXLine(g2, r, xxline, xuxianbs, bases);
								}
								g2.draw(r);
								System.out.println(r);
							}
						}
						System.out.println("=============================       " + iname + "             ===========================");
						ImageIO.write(img, "JPEG", new FileOutputStream(new File("d:/1/"+iname+".jpg")));
						img = new BufferedImage((int)huabu.getWidth(), (int)huabu.getHeight(), BufferedImage.TYPE_INT_RGB);
						g2 = (Graphics2D)img.getGraphics();
						g2.setStroke(bases);
						g2.setColor(Color.WHITE);
						g2.setBackground(Color.WHITE);
						g2.fill(huabu);
						g2.setColor(Color.RED);
						outside.setRect(0, 0, outside.getWidth() - LINEPX, outside.getHeight() - LINEPX);
						g2.draw(huabu);
						g2.setColor(Color.BLACK);
					}
					img = new BufferedImage((int)huabu.getWidth(), (int)huabu.getHeight(), BufferedImage.TYPE_INT_RGB);
					g2 = (Graphics2D)img.getGraphics();
					g2.setStroke(bases);
					g2.setColor(Color.WHITE);
					g2.setBackground(Color.WHITE);
					g2.fill(huabu);
					g2.setColor(Color.RED);
					outside.setRect(0, 0, outside.getWidth() - LINEPX, outside.getHeight() - LINEPX);
					g2.draw(huabu);
					g2.setColor(Color.BLACK);
			}
//------------------debug code row end ----------------------------------------------------------------------------------------
			for(int i = 1; i <= maxresult.description.size(); i++){
				for(Rectangle2D r : maxresult.description.get(i)){
					if(isbook){
						drawXXLine(g2, r, xxline, xuxianbs, bases);
					}
					g2.draw(r);
					if(debug){
						System.out.println(r);
					}
				}
			}
			System.out.println(maxresult.total);
			resultoutfile.deleteOnExit();
			if(debug){
				ImageIO.write(img, "JPEG", new FileOutputStream(new File("d:/1/"+(iname+1)+".jpg")));
			}else{
				ImageIO.write(img, "JPEG", new FileOutputStream(resultoutfile));
			}
			return maxresult;
		}
	}
	
	private int getMaxiMum(Rectangle2D outside, Rectangle2D inside){//          2                   
		double a_w = outside.getWidth();
		double a_h = outside.getHeight();
		double b_w = inside.getWidth();
		double b_h = inside.getHeight();
		double d_temp = 0d;
		if(a_w < a_h){
		    d_temp = a_w;   
		    a_w = a_h;
		    a_h = d_temp;
		}
		if(b_w < b_h){
			d_temp = b_w;
		    b_w = b_h;
		    b_h = d_temp;
		}
		
		getMaxiMumOne(a_w, a_h, b_w, b_h, 3, outside); //                      1  
		
		getMaxiMumTwo(a_w, a_h, b_w, b_h, 3, outside); //   2              
		
		//                     
		for(HspaiResult r : relist){//           
			if(maxresult == null && r != null){
				maxresult = r;
			}else if(r != null && maxresult.total < r.total){
				maxresult = r;
			}
		}
		
		if(maxresult != null){
			return maxresult.total;
		}
		
		return 0;
	}
	
	private void getMaxiMumOne(double a_w, double a_h, double b_w, double b_h, int type, Rectangle2D outside){//       1          
		int sp_total = (int)((a_w/b_w) * (a_h/b_h));
		List<Rectangle2D> dep_arl = null;
		HashMap<Integer, List<Rectangle2D>> description = null;
		HspaiResult re_temp = null;
		Rectangle2D rectangle2d_cell_temp = null;
		int max_sp = (int)(a_w / b_h);
		double last_sz_hight = 0d;//         ,          
		boolean isDown = false;//               
		for(int i = 1; i <= sp_total; i++){
			if(isDown){//                   
				break;
			}
			int row = 1;
			re_temp = new HspaiResult();
			description = new HashMap<Integer, List<Rectangle2D>>();
			dep_arl = new LinkedList<Rectangle2D>();
			re_temp.description = description; 
			description.put(row, dep_arl);
			int first_add_sp_row = i % max_sp == 0 ? i / max_sp : (i / max_sp + 1);
			first_add_sp_row = first_add_sp_row == 0 ? 1 : first_add_sp_row;
			float first_sp_x = 0F;
			float first_sp_y = 0F;
			for(int iii = 1; iii <= i; iii++){//          
				if(a_w - first_sp_x < b_h){//              
					first_sp_y += b_w;
					if(a_h - first_sp_y < b_w){//              
						isDown = true;
						break;
					}
					dep_arl = new LinkedList<Rectangle2D>();
					description.put(++row, dep_arl);
					first_sp_x = 0F;
					rectangle2d_cell_temp = new Rectangle2D.Float(first_sp_x, first_sp_y, (float)b_h, (float)b_w);
					dep_arl.add(rectangle2d_cell_temp);
					++re_temp.total;
				}else{//    
					rectangle2d_cell_temp = new Rectangle2D.Float(first_sp_x, first_sp_y, (float)b_h, (float)b_w);
					dep_arl.add(rectangle2d_cell_temp);
					++re_temp.total;
				}
				if(rectangle2d_cell_temp.getY() + rectangle2d_cell_temp.getHeight() > last_sz_hight){
					last_sz_hight = rectangle2d_cell_temp.getY() + rectangle2d_cell_temp.getHeight();
				}
				first_sp_x += b_h;
			}
			Rectangle2D last_sp = rectangle2d_cell_temp;
			double x = 0d;
			double y = 0d;
			//             
			if(last_sp != null){
				while(true){
					if(a_w - rectangle2d_cell_temp.getX() - rectangle2d_cell_temp.getWidth() < b_w){ //           
							if(rectangle2d_cell_temp == last_sp){//        
								if(a_h - last_sz_hight < b_h){
									break;
								}
							}else{
								if(last_sz_hight > rectangle2d_cell_temp.getY() + rectangle2d_cell_temp.getHeight()){
									if(a_h - last_sz_hight < b_h){
										break;
									}
								}else if(a_h - rectangle2d_cell_temp.getY() - rectangle2d_cell_temp.getHeight() < b_h){
									break;
								}
							}
					}
					if(rectangle2d_cell_temp == last_sp){//                         
						if(a_w - last_sp.getX() - last_sp.getWidth() >= b_w){//         
							x = last_sp.getX() + last_sp.getWidth();
							y = last_sp.getY();
						}else{
							dep_arl = new LinkedList<Rectangle2D>();
							description.put(++row, dep_arl);
							x = 0;
							y = last_sp.getY() + last_sp.getHeight();
						}
					}else{//        
						if(a_w - rectangle2d_cell_temp.getX() - rectangle2d_cell_temp.getWidth() >= b_w){
							x = rectangle2d_cell_temp.getX() + rectangle2d_cell_temp.getWidth();
							y = rectangle2d_cell_temp.getY();
						}else{//  ,           
							dep_arl = new LinkedList<Rectangle2D>();
							description.put(++row, dep_arl);
							if(last_sz_hight - rectangle2d_cell_temp.getY() - rectangle2d_cell_temp.getHeight() >= b_h){//            (     )
								x = last_sp.getX() + last_sp.getWidth();
								y = rectangle2d_cell_temp.getY() + rectangle2d_cell_temp.getHeight();
							}else{
								x = 0d;
								if(last_sz_hight > rectangle2d_cell_temp.getY() + rectangle2d_cell_temp.getHeight()){
									y = last_sz_hight;
								}else{
									y = rectangle2d_cell_temp.getY() + rectangle2d_cell_temp.getHeight();
								}
							}
						}
					}
					rectangle2d_cell_temp = new Rectangle2D.Double(x, y, b_w, b_h);
					dep_arl.add(rectangle2d_cell_temp);
					++re_temp.total;
				}
			}else{//         
				dep_arl = new LinkedList<Rectangle2D>();
				description.put(++row, dep_arl);
				rectangle2d_cell_temp = new Rectangle2D.Double(0d, 0d, b_w, b_h);
				dep_arl.add(rectangle2d_cell_temp);
				++re_temp.total;
				isDown = true;
			}
			relist.add(re_temp);
		}
	}
	
	private void getMaxiMumTwo(double a_w, double a_h, double b_w, double b_h, int type, Rectangle2D outside){//       2                   
		int hp_total = (int)((a_w/b_w) * (a_h/b_h));
		List<Rectangle2D> dep_arl = null;
		HashMap<Integer, List<Rectangle2D>> description = null;
		HspaiResult re_temp = null;
		Rectangle2D rectangle2d_cell_temp = null;
		int max_sp = (int)(a_w / b_h);
		boolean isDown = false;//               
		for(int i = 1; i <= hp_total; i++){
			if(isDown){//                   
				break;
			}
			int row = 1;
			re_temp = new HspaiResult();
			description = new HashMap<Integer, List<Rectangle2D>>();
			dep_arl = new LinkedList<Rectangle2D>();
			re_temp.description = description; 
			description.put(row, dep_arl);
			int first_add_sp_row = i % max_sp == 0 ? i / max_sp : (i / max_sp + 1);
			first_add_sp_row = first_add_sp_row == 0 ? 1 : first_add_sp_row;
			double hx = 0d;
			double hy = 0d;
			for(int iii = 1; iii <= i; iii++){//          
				while(true){//     
					if(a_w - hx - b_w < b_w){//          
						if(a_h - hy < b_h){//               
							isDown = true;
							break;
						}
					}
					//    
					if(a_h - hy < b_h){
						break;
					}else{
						rectangle2d_cell_temp = new Rectangle2D.Double(hx, hy, b_w, b_h);
						dep_arl.add(rectangle2d_cell_temp);
						++re_temp.total;
						hy += b_h;
					}
				}
				if(isDown){
					break;
				}
				if(iii != i){
					hx += b_w;
					hy = 0d;
					dep_arl = new LinkedList<Rectangle2D>();
					description.put(++row, dep_arl);
				}
			}
//			Rectangle2D last_sp = rectangle2d_cell_temp;//           
			double x = hx + b_w;
			double y = 0d;
			//             
			if(a_w - x >= b_h){
				while(true){
					if(a_h - y < b_w){//    
						if(a_w - x - b_h < b_h){//                    
							break;
						}
						dep_arl = new LinkedList<Rectangle2D>();
						description.put(++row, dep_arl);
						y = 0d;
						x += hx + b_h;
					}
					rectangle2d_cell_temp = new Rectangle2D.Double(x, y, b_h, b_w);
					dep_arl.add(rectangle2d_cell_temp);
					++re_temp.total;
					y += b_w;
				}
			}
			relist.add(re_temp);
		}
	}
	
	/**
	 *            
	 * @param out    
	 * @param ins    
	 * @return     
	 */
	private Rectangle2D getBigRect(Rectangle2D out, Rectangle2D ins){
		double a_w = out.getWidth();
		double a_h = out.getHeight();
		double b_w = ins.getWidth();
		double b_h = ins.getHeight();
		double d_temp=0d;
		if(a_w < a_h){
		    d_temp = a_w;   
		    a_w = a_h;
		    a_h = d_temp;
		}
		if(b_w < b_h){
			d_temp = b_h;
		    b_h = b_w;
		    b_w = d_temp;
		}
		double w = a_w + ((int)(a_w / b_h) + 1) * LINEPX;
		double h = a_h + ((int)(a_h / b_h) + 1) * LINEPX;
		return new Rectangle2D.Double(0d, 0d, w, h);
	}
	
	public static DrawKL getInstanse(){
		return new DrawKL();
	}
	
	private DrawKL() {
	}
	
	/**
	 *        
	 * @author     
	 *
	 */
	public class HspaiResult{
		/**
		 *     
		 */
		public int total = 0;
		/**
		 *     
		 * key      1 2 3    
		 */
		public HashMap<Integer, List<Rectangle2D>> description = null;
		/**
		 *       
		 */
		public double clxl = 0d;
		/**
		 *        
		 */
		public Rectangle2D outside = null;
		public Rectangle2D inside = null;
		/**
		 *        
		 */
		public String filepath = null;
		/**
		 *      
		 */
		public double papernum = 0d;
	}
	/**
	 *              
	 * @param g2    
	 * @param r       
	 * @param xxline          
	 * @param xuxianbs      
	 * @param bases       
	 */
	private void drawXXLine(Graphics2D g2, Rectangle2D r, Line2D xxline, BasicStroke xuxianbs, BasicStroke bases){
		g2.setStroke(xuxianbs);
		g2.setColor(Color.RED);
		if(r.getWidth() > r.getHeight()){
			xxline.setLine(r.getX() + (r.getWidth() / 2), r.getY(), r.getX() + (r.getWidth() / 2), r.getY()+r.getHeight());
		}else{
			xxline.setLine(r.getX(), r.getY() + (r.getHeight() / 2), r.getX() + r.getWidth(), r.getY() + (r.getHeight() / 2));
		}
		g2.draw(xxline);
		g2.setStroke(bases);
		g2.setColor(Color.BLACK);
	}
	/**
	 *        
	 * @param     
	 * @return    
	 */
	private double getClxl(HspaiResult resu) {
		double a_in_m = resu.inside.getWidth() * resu.inside.getHeight() * resu.total;
		double a_ou_m = resu.outside.getWidth() * resu.outside.getHeight();
		return BigDecimal.valueOf((a_in_m / a_ou_m) * 100).setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
	}
	
	private File resultoutfile = null;  //                  
	private HspaiResult maxresult = null; //                  
	private List<HspaiResult> relist = new LinkedList<HspaiResult>(); //                 
	private final static int LINEPX = 1; //           
	private boolean isbook = false;//     
	//          
	private BasicStroke xuxianbs = null;
	private Line2D xxline = null;
}