小工具DeTexturepacker

用texturepacker打包了素材,不小心把原来的素材丢掉了;或则打开了别人的apk,想用里面的素材做一些练习。针对这些场景,我写了个小工具分享给大家。

附录是个打包好的jar文件(需要java环境才能够运行),解压后目录中有3个文件,jar和两个素材。切换到目录,运行如下命令就可以把素材还原到result目录下:

java -jar DeTexturepacker.jar Common1

下面是工具的源代码:

package com.detp;

import java.awt.Graphics;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;


public class Decoder {
	public static String pngname = "";
	public static String plistname = "";
	public static void main(String[] args) throws Exception {
		
		if(args.length==1) {
			pngname = args[0] + ".png";
			plistname = args[0] + ".plist";
		} else if(args.length==2) {
			for(String arg : args) {
				if(arg.contains("png")) {
					pngname = arg;
				} else if(arg.contains("plist")) {
					plistname = arg;
				}
			}
		} else {
			System.out.println("Usage: 1) DeTexturepacker name  2) DeTexturepacker name.plist name.png\n");
			return;
		}
		delImg();
	}
	
	private static void delImg() throws Exception {
		InputStream is =   new FileInputStream( pngname );
		BufferedImage image = ImageIO.read(is);
		File fold = new File("result");
		if(fold.exists()) {
			fold.delete();
		}
		fold.mkdir();
		ArrayList<Frame> frames = exactData().frames;
		for(Frame f : frames) {
			System.out.print(".");
			try {
				f.split(image, "result");
			}catch(Exception e) {
				System.err.print("===>" +f.toString());
				e.printStackTrace();
			}
		}
		System.out.println("Done!\n");
	}
	
	private static PlistData exactData() throws Exception {
		PlistData pd = new PlistData();
		String con = getContent();
		
		Pattern p = Pattern.compile("<key>frames</key>[^<]+<[^<]+(.+)");
		Matcher m = p.matcher(con);
		if(m.find()) {
			con = m.group(1);
			p = Pattern.compile("<key>([^<]+)<[^<]+<dict>(.*?)</dict>");
			m = p.matcher(con);
			
			Pattern pc = Pattern.compile("<key>([^<]+)</key>[^<]+<([^<]+)");
			while(m.find()) {
				if(m.group(1).equals("metadata")) {
				} else {
					Frame f = new Frame();
					pd.add(f);
					f.filename = m.group(1);
					Matcher mc = pc.matcher(m.group(2));
					while(mc.find()){
						f.set(mc.group(1), mc.group(2));
					}
				}
			}
		}
		return pd;
	}
	
	private static String getContent() throws IOException {
		InputStream is = new FileInputStream( plistname);
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		String line;
		StringBuilder sb = new StringBuilder();
		while((line=reader.readLine())!=null) {
			sb.append(line);
//			System.out.println(line);
		}
		return sb.toString();
	}
}



class Frame {
	public String filename;
	public Rect frame, sourceColorRect;
	public Vec2 offset, size;
	public boolean rotated;
	
	public void set(String key, String val) {
		if(key.equals("frame")) {
			frame = new Rect(val);
		} else if(key.equals("offset")) {
			offset = new Vec2(val);
		} else if(key.equals("rotated")) {
			rotated = val.contains("true");
		} else if(key.equals("sourceColorRect")) {
			sourceColorRect = new Rect(val);
		} else if(key.equals("sourceSize")) {
			size = new Vec2(val);
		} 
	}
	
	public void split(BufferedImage image, String root) throws IOException {
		if(filename.contains("/")) {
			String[] fs = filename.split("/");
			String ff = root;
			for(int i=0; i<fs.length-1; i++) {
				ff += "/" + fs[i];
				File mf = new File(ff);
				if(!mf.exists()) {
					mf.mkdir();
				}
			}
		}
		BufferedImage si = null;
		if(rotated) {
			si = rotateImg(image.getSubimage(frame.x1, frame.y1, frame.y2, frame.x2));
		} else {
			si = image.getSubimage(frame.x1, frame.y1, frame.x2, frame.y2);
		}
		si = changeSize(si);
		ImageIO.write(si, "png", new File(String.format("%s/%s", root, filename)));
	}
	
	private BufferedImage rotateImg(BufferedImage bufferedImage) {
		int width = bufferedImage.getWidth(), height = bufferedImage.getHeight();
		int max = width > height ? width : height;
		
		BufferedImage tmp = new BufferedImage(max, max, BufferedImage.TYPE_INT_ARGB);
		Graphics g = tmp.getGraphics();
		g.drawImage(bufferedImage, (max-width)/2, (max-height)/2, null);
		
		 AffineTransform transform = new AffineTransform();
		 transform.rotate(-Math.PI/2, max/2, max/2);
		 AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
		 tmp = op.filter(tmp, null);
		 try {
			 tmp = tmp.getSubimage((max-height)/2, (max-width)/2, height, width); 
		 }catch(Exception e) {
			 tmp = tmp.getSubimage((max-height)/2, (max-width)/2, height-1, width-1); 
			 System.err.println("Frame#rotateImg fix");
		 }
		 
		 return tmp;
	}
	
	private BufferedImage changeSize(BufferedImage bufferedImage){
		BufferedImage tmp = new BufferedImage(size.x, size.y, BufferedImage.TYPE_INT_ARGB);
		Graphics g = tmp.getGraphics();
		int x = (size.x - bufferedImage.getWidth())/2 + offset.x;
		int y = (size.y - bufferedImage.getHeight())/2 - offset.y;
		g.drawImage(bufferedImage, x, y, null);
		return tmp;
	}
	
	public String toString() {
		return String.format("%s\tframe:%s, offset:%s, rotated:%s, sourceColorRect:%s, sourceSize:%s\n", 
				filename, frame, offset, rotated?"true":"false", sourceColorRect, size);
	}
	
}

class PlistData {
	public ArrayList<Frame> frames = new ArrayList<Frame>();
	public void add(Frame f) {
		frames.add(f);
	}
}

class Vec2 {
	static Pattern p = Pattern.compile("(-?\\d+),(-?\\d+)");
	public int x, y;
	public Vec2(String val) {
		Matcher m = p.matcher(val);
		if(m.find()) {
			x = Integer.parseInt(m.group(1));
			y = Integer.parseInt(m.group(2));
		}else {
			System.err.println(val + " is not a Vec2!!");
		}
	}
	public Vec2(int _x, int _y) {
		x = _x;
		y = _y;
	}
	public String toString() {
		return "(" + x + "," + y + ")";
	}
}

class Rect {
	static Pattern p = Pattern.compile("(-?\\d+),(-?\\d+)[^\\d]+(-?\\d+),(-?\\d+)");
	public int x1,y1, x2, y2;
	public Rect(String val) {
		Matcher m = p.matcher(val);
		if(m.find()) {
			x1 = Integer.parseInt(m.group(1));
			y1 = Integer.parseInt(m.group(2));
			x2 = Integer.parseInt(m.group(3));
			y2 = Integer.parseInt(m.group(4));
		}else {
			System.err.println(val + " is not a Rect!!");
		}
	}
	public Rect(int _x1, int _y1,int _x2, int _y2) {
		x1 = _x1;
		y1 = _y1;
		x2 = _x2;
		y2 = _y2;
	}
	public String toString() {
		return String.format("((%d,%d),(%d,%d))", x1,y1, x2, y2);
	}
}


工具下载地址:

http://download.csdn.net/detail/stalendp/6783755

你可能感兴趣的:(java,小工具,源代码,TexturePacker)