android mninenine patch editorchunk null 是什么意思

&& 最近在工作中需要解析点9图的头信息(chunk)的格式,读取拉伸坐标片段、padding信息,在网上找了一下没有相关信息,下面详解一下解析过程。
&&& 点9图的定义见官方文档:/guide/topics/graphics/2d-graphics.html#nine-patch
&&& 简单来说就是左边的点代表垂直拉伸的区域,上边的点代表水平拉伸的区域;右边的点代表文字等的垂直可可显示区域,下边的点代表文字等的水平可显示区域。所以,左上重合的区域就是拉伸区域;右下重合的区域就是显示区域。
& & Android的编译工具aapt会把标记了拉伸区域的点9图处理成一个普通的png,并把相关的信息放入png头部的meta-data区域,即chunk。这个过程详见frameworks/base/tools/aapt/Images.cpp的static status_t do_9patch(const char* imageName, image_info* image)
PNG文件结构
&&& 官方文档参见右边的链接:,摘抄部分如下
&&& A PNG always starts with an 8-byte signature: 137 80 78 71 13 10 26 10 (decimal values). The remainder of the file consists a series of chunks beginning with an IHDR chunk and ending with an IEND chunk.
&&& 好了,了解了PNG的文件结构我们就可以取出chunk了,只需要按照文档的说明,按顺序取出Chunk data对应的信息即可。特别需要注意的是,读取字节流的时候需要采取大端方式。下面上代码
* PNG Chunk struct
* &a href=&http://dev.exiv2.org/projects/exiv2/wiki/The_Metadata_in_PNG_files&&The Metadata in PNG files&/a&
+--------+---------+
| Length | 4 bytes |
+--------+---------+
| 4 bytes |
+--------+---------+
+--------+---------+
| 4 bytes |
+--------+---------+
* @param pngName
* @return chunk
* @throws IOException
private byte[] loadNinePatchChunk(InputStream is) throws IOException {
IntReader reader = new IntReader(is, true);
// check PNG signature
// A PNG always starts with an 8-byte signature: 137 80 78 71 13 10 26 10 (decimal values).
if (reader.readInt() != 0x89504e47 || reader.readInt() != 0x0D0A1A0A) {
while (true) {
int length = reader.readInt();
int type = reader.readInt();
// check for nine patch chunk type (npTc)
if (type != 0x6E705463) {
reader.skip(length + 4/*crc*/);
return reader.readByteArray(length);
&&& 点9图的Chunk是按照struct Res_png_9patch的结构组织的,详见frameworks/base/include/androidfw/ResourceTypes.h。
struct Res_png_9patch
Res_png_9patch() : wasDeserialized(false), xDivs(NULL),
yDivs(NULL), colors(NULL) { }
int8_t wasD
int8_t numXD
int8_t numYD
int8_t numC
// These tell where the next section of a patch starts.
// For example, the first patch includes the pixels from
// 0 to xDivs[0]-1 and the second patch includes the pixels
// from xDivs[0] to xDivs[1]-1.
// Note: allocation/free of these pointers is left to the caller.
int32_t* xD
int32_t* yD
int32_t paddingLeft, paddingR
int32_t paddingTop, paddingB
// The 9 patch segment is not a solid color.
NO_COLOR = 0x,
// The 9 patch segment is completely transparent.
TRANSPARENT_COLOR = 0x
// Note: allocation/free of this pointer is left to the caller.
// Convert data from device representation to PNG file representation.
void deviceToFile();
// Convert data from PNG file representation to device representation.
void fileToDevice();
// Serialize/Marshall the patch data into a newly malloc-ed block
void* serialize();
// Serialize/Marshall the patch data
void serialize(void* outData);
// Deserialize/Unmarshall the patch data
static Res_png_9patch* deserialize(const void* data);
// Compute the size of the serialized data structure
size_t serializedSize();
};& 了解了struct Res_png_9patch,我们只需根据struct Res_png_9patch的结构解析上面步骤得到的chunk data即可。代码如下:
public static NinePatchChunk deserialize(byte[] data) {
ByteBuffer byteBuffer = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN);
byte wasSerialized = byteBuffer.get();
if (wasSerialized == 0)
NinePatchChunk chunk = new NinePatchChunk();
chunk.mDivX = new int[byteBuffer.get()];
chunk.mDivY = new int[byteBuffer.get()];
chunk.mColor = new int[byteBuffer.get()];
checkDivCount(chunk.mDivX.length);
checkDivCount(chunk.mDivY.length);
// skip 8 bytes
byteBuffer.getInt();
byteBuffer.getInt();
chunk.mPaddings.left = byteBuffer.getInt();
chunk.mPaddings.right = byteBuffer.getInt();
chunk.mPaddings.top = byteBuffer.getInt();
chunk.mPaddings.bottom = byteBuffer.getInt();
// skip 4 bytes
byteBuffer.getInt();
readIntArray(chunk.mDivX, byteBuffer);
readIntArray(chunk.mDivY, byteBuffer);
readIntArray(chunk.mColor, byteBuffer);
}&&& NinePatchChunk.mDivX和NinePatchChunk.mDivY就是点9图的拉伸区域标识信息,NinePatchChunk.mPaddings是点9图的pading信息,这样点9图的Chunk信息就解析完毕了。
&&& 全部代码见/luxiaoyu/d7c57a18c5
&&& 调研这种SDK文档上没有详细信息的数据结构,需要从Android源码入手,耐心查看相关代码和注释,grep和find是好帮手。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:155次
排名:千里之外

我要回帖

更多关于 android ninepatch 的文章

 

随机推荐