用TexturePacker将多张png小图片合成大图片,生成 .xml索引文件
symbain同步解析xml文件有点麻烦,直接转ini文件,代码如下:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: wulong
* Date: 12-3-19
* Time: 下午2:15
* To change this template use File | Settings | File Templates.
*/
public class MyTools {
private static void printf(Object obj) {
System.out.println("hai:::" + obj);
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
MyTools intent = new MyTools();
intent.begin();
}
void begin() {
final String mPath = System.getProperty("user.dir") + "\\out\\production\\PicTools\\";
printf("mpath = " + mPath);
ArrayList<String> fileList = readFileName(mPath);
printf("得到文件数目 " + fileList.size());
printf("得到文件名 " + fileList.toString());
for (int i = 0; i < fileList.size(); i++) {
List<XmParam> iniArr = new ArrayList<XmParam>();
String srcName = fileList.get(i);
decodeXml(mPath, srcName,iniArr);
writeIni(mPath, srcName, iniArr);
}
}
void writeIni(String path, String file, List<XmParam> arr) {
String[] sp = file.split("\\.");//'.'号需要用转义字符表示
if (sp.length > 1 && sp[sp.length - 1].equals("xml")) {
file = file.substring(0, file.length() - 4);
}
printf("sub string path = " + path);
printf("sub string file = " + file);
file = path + file + ".ini";
createFile(file);
IniFile intent = new IniFile();
intent.load(file);
for (XmParam e : arr) {
intent.setValue(e.n, "x", "" + e.x);
intent.setValue(e.n, "y", "" + e.y);
intent.setValue(e.n, "w", "" + e.w);
intent.setValue(e.n, "h", "" + e.h);
intent.setValue(e.n, "oX", "" + e.oX);
intent.setValue(e.n, "oY", "" + e.oY);
intent.setValue(e.n, "oW", "" + e.oW);
intent.setValue(e.n, "oH", "" + e.oH);
intent.setValue(e.n, "r", "" + e.r);
}
intent.write(file);
}
/**
* 删除单个文件
*
* @param fileName 被删除文件的文件名
* @return 单个文件删除成功返回true, 否则返回false
*/
public static boolean deleteFile(String fileName) {
File file = new File(fileName);
if (file.isFile() && file.exists()) {
file.delete();
System.out.println("删除单个文件" + fileName + "成功!");
return true;
} else {
System.out.println("删除单个文件" + fileName + "失败!");
return false;
}
}
/**
* 删除单个文件
*
* @param fileName 被删除文件的文件名
* @return 单个文件删除成功返回true, 否则返回false
*/
public boolean createFile(String fileName) {
deleteFile(fileName);
try {
File file = new File(fileName);
file.createNewFile();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
* 查找指定文件夹下文件
*
* @return
*/
public ArrayList<String> readFileName(final String path) {
Integer fileCount = 0;
File file = new File(path);
String[] list = file.list();
ArrayList<String> fileList = new ArrayList<String>();
if (null == list) {
return fileList;
}
for (int i = 0; i < list.length; i++) {
File f = new File(path + "\\" + list[i]);
if (f.isFile()) {
fileCount++;
String name = f.getName();
printf("file name fileCount[" + fileCount + "]=" + name);
String[] sp = name.split("\\.");//'.'号需要用转义字符表示
if (sp.length > 1 && sp[sp.length - 1].equals("xml")) {
fileList.add(f.getName());
}
}
}
return fileList;
}
public void decodeXml(final String path, String name, List<XmParam> arr) {
String uri = path + name;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
// <sprite n="icon_agg_img_1053" x="80" y="70" w="74" h="68" oX="4" oY="0" oW="76" oH="76" r="y"/>
DocumentBuilder builder = factory.newDocumentBuilder();
//xml文件路径
Document doc = (Document) builder.parse(uri);
NodeList nodeList = doc.getElementsByTagName("TextureAtlas");
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
//获取所有元素名称为b的节点
NodeList nlist = element.getElementsByTagName("sprite");
for (int j = 0; j < nlist.getLength(); j++) {
XmParam e = new XmParam();
Element root = (Element) nlist.item(j);
//根据key值sid获取节点属性值
e.n = root.getAttribute("n");
e.x = root.getAttribute("x");
e.y = root.getAttribute("y");
e.w = root.getAttribute("w");
e.h = root.getAttribute("h");
e.oX = root.getAttribute("oX");
e.oY = root.getAttribute("oY");
e.oW = root.getAttribute("oW");
e.oH = root.getAttribute("oH");
e.r = root.getAttribute("r");
arr.add(e);
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
class XmParam {
String n, x, y, w, h, oX, oY, oW, oH, r;
}
}
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Created by IntelliJ IDEA.
* User: wulong
* Date: 12-3-19
* Time: 下午4:09
* To change this template use File | Settings | File Templates.
*/
class IniFile {
String RT = "\r\n";
private final static Map<String, Map<String, Object>> iniFile = new HashMap<String, Map<String, Object>>();
public IniFile() {
}
final public static synchronized void setValue(String section, String key,
Object value) {
Map<String, Object> sectionMap = iniFile.get(section);
if (sectionMap == null) {
sectionMap = new HashMap<String, Object>();
iniFile.put(section, sectionMap);
}
sectionMap.put(key, value);
}
final public static synchronized Object getValue(String section, String key) {
Object obj = null;
Map<String, Object> item = iniFile.get(section);
if (item != null) {
obj = item.get(key);
}
return obj;
}
final public synchronized void load(String path) {
try {
DataInputStream ds = new DataInputStream(new FileInputStream(path));
String str = ds.readLine();
String section = null;
while (str != null) {
// System.out.println(str);
if (str.startsWith("[")) {
Map<String, Object> itemMap = new HashMap<String, Object>();
section = str.substring(1, str.length() - 1);
// System.out.println(section);
iniFile.put(section, itemMap);
} else {
Map<String, Object> itemMap = iniFile.get(section);
String key = str.substring(0, str.indexOf("="));
String value = str.substring(str.indexOf("=") + 1);
itemMap.put(key, value);
}
str = ds.readLine();
}
ds.close();
} catch (IOException e) {
e.printStackTrace();
}
}
final public synchronized void write(String name) {
try {
StringBuilder sb = new StringBuilder("");
for (String section : iniFile.keySet()) {
sb.append("[").append(section).append("]").append(RT);
Map<String, Object> map = iniFile.get(section);
Set<String> keySet = map.keySet();
for (String key : keySet) {
sb.append(key).append("=").append(map.get(key)).append(RT);
}
sb.append(RT);
}
File file = new File(name);
if (!file.exists()) {
file.createNewFile();
}
OutputStream os = new FileOutputStream(file);
os.write(sb.toString().getBytes());
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试文件:
youare.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with TexturePacker http://texturepacker.com-->
<!-- -->
<!--Format:
n => name of the sprite
x => sprite x pos in texture
y => sprite y pos in texture
w => sprite width (may be trimmed)
h => sprite height (may be trimmed)
oX => sprite's x-corner offset (only available if trimmed)
oY => sprite's y-corner offset (only available if trimmed)
oW => sprite's original width (only available if trimmed)
oH => sprite's original height (only available if trimmed)
r => 'y' only set if sprite is rotated
-->
<TextureAtlas imagePath="youare.png" width="256" height="512">
<sprite n="icon_agg_img_1053" x="80" y="70" w="74" h="68" oX="4" oY="0" oW="76" oH="76" r="y"/>
<sprite n="icon_agg_img_1054" x="152" y="144" w="72" h="68" oX="4" oY="1" oW="76" oH="76" r="y"/>
<sprite n="icon_agg_img_1055" x="2" y="140" w="74" h="62" oX="7" oY="1" oW="76" oH="76" r="y"/>
<sprite n="icon_agg_img_1056" x="158" y="2" w="74" h="72" oX="1" oY="2" oW="76" oH="76"/>
<sprite n="icon_agg_img_1057" x="2" y="2" w="76" h="68" oX="4" oY="0" oW="76" oH="76" r="y"/>
<sprite n="icon_agg_img_1062" x="2" y="204" w="72" h="68" oX="4" oY="1" oW="76" oH="76" r="y"/>
<sprite n="icon_agg_img_1063" x="156" y="76" w="74" h="66" oX="5" oY="1" oW="76" oH="76" r="y"/>
<sprite n="icon_agg_img_1064" x="2" y="72" w="74" h="66" oX="5" oY="0" oW="76" oH="76" r="y"/>
<sprite n="icon_agg_img_1065" x="78" y="140" w="72" h="68" oX="4" oY="1" oW="76" oH="76" r="y"/>
<sprite n="icon_agg_img_1066" x="80" y="2" w="76" h="66" oX="5" oY="0" oW="76" oH="76" r="y"/>
</TextureAtlas>
转换后的结果:
youare.ini
[icon_agg_img_1066]
w=76
r=y
oH=76
oY=0
oX=5
h=66
y=2
oW=76
x=80
[icon_agg_img_1065]
w=72
r=y
oH=76
oY=1
oX=4
h=68
y=140
oW=76
x=78
[icon_agg_img_1064]
w=74
r=y
oH=76
oY=0
oX=5
h=66
y=72
oW=76
x=2
[icon_agg_img_1063]
w=74
r=y
oH=76
oY=1
oX=5
h=66
y=76
oW=76
x=156
[icon_agg_img_1062]
w=72
r=y
oH=76
oY=1
oX=4
h=68
y=204
oW=76
x=2
[icon_agg_img_1053]
w=74
r=y
oH=76
oY=0
oX=4
h=68
y=70
oW=76
x=80
[icon_agg_img_1056]
w=74
r=
oH=76
oY=2
oX=1
h=72
y=2
oW=76
x=158
[icon_agg_img_1054]
w=72
r=y
oH=76
oY=1
oX=4
h=68
y=144
oW=76
x=152
[icon_agg_img_1057]
w=76
r=y
oH=76
oY=0
oX=4
h=68
y=2
oW=76
x=2
[icon_agg_img_1055]
w=74
r=y
oH=76
oY=1
oX=7
h=62
y=140
oW=76
x=2