我对Android应用程序有一个要求,即通过从服务器端检索新的颜色和图像,图形的各个部分应可自定义。其中一些图像是9色块图像。
我找不到创建和显示这些 9-patch 图像(已通过网络检索到的图像)的方法。
检索 9-patch 图像并将其作为位图保存在应用程序中。为了创建NinePatchDrawable,您需要相应的NinePatch或NinePatch的块(byte[]
)。无法从资源加载NinePatch,因为/res/drawable/
中不存在图像。此外,为了创建NinePatch,您需要NinePatch的块。因此,这一切都深入到了大块。
那么问题是,如何从现有的位图(包含NinePatch信息)格式化/生成块?
我已经搜索了Android源代码和Web,但似乎找不到任何示例。更糟的是,对NinePatch资源的所有解码似乎都是本地完成的。
有没有人对这种问题有任何经验?
我的目标是API级别4,如果那很重要的话。
最佳答案
getNinePatchChunk
可以正常工作。它返回空值,因为您为Bitmap
提供了一个“源” ninepatch。它需要一个“已编译”的ninepatch镜像。
Android世界中有两种类型的ninepatch文件格式(“源”和“已编译”)。在源版本中,您可以在各处添加1px透明边框-稍后将应用编译为.apk时,aapt会将* .9.png文件转换为Android期望的二进制格式。这是png文件获取其“块”元数据的地方。 (read more)
好的,现在开始做生意(您正在听DJ kanzure)。
InputStream stream = .. //whatever
Bitmap bitmap = BitmapFactory.decodeStream(stream);
byte[] chunk = bitmap.getNinePatchChunk();
boolean result = NinePatch.isNinePatchChunk(chunk);
NinePatchDrawable patchy = new NinePatchDrawable(bitmap, chunk, new Rect(), null);
另外:我不知道
BitmapFactory.decodeStream
是否了解这些png文件中的npTc块,因此它可能会或可能不会正确处理图像流。 Bitmap.getNinePatchChunk
的存在表明BitmapFactory
可能-您可以在上游代码库中查找它。如果它不知道npTc块,并且您的图像被严重破坏,那么我的答案会有所变化。
您无需编写快速的Android应用程序来加载已编译的图像并吐出
byte[]
块,而无需将已编译的ninepatch图像发送给客户端。然后,您将此字节数组与常规图像一起发送给客户端-没有透明边框,不是“源” ninepatch图像,不是“已编译” ninepatch图像。您可以直接使用块来创建您的对象。另一个替代方法是使用对象序列化向您的客户端发送ninepatch图像(
NinePatch
),例如使用JSON或内置序列化器。编辑如果确实需要构造自己的块字节数组,我将首先查看ResourceTypes.cpp中的
do_9patch
,isNinePatchChunk
,Res_png_9patch
和Res_png_9patch::serialize()
。还有一个来自德米特里·斯基巴(Dmitry Skiba)的自制npTc块读取器。我无法发布链接,因此,如果有人可以编辑我的答案,那将很酷。do_9patch:
https://android.googlesource.com/platform/frameworks/base/+/gingerbread/tools/aapt/Images.cpp
isNinePatchChunk:http://netmite.com/android/mydroid/1.6/frameworks/base/core/jni/android/graphics/NinePatch.cpp
struct Res_png_9patch:https://scm.sipfoundry.org/rep/sipX/main/sipXmediaLib/contrib/android/android_2_0_headers/frameworks/base/include/utils/ResourceTypes.h
德米特里·斯基巴(Dmitry Skiba)的东西:http://code.google.com/p/android4me/source/browse/src/android/graphics/Bitmap.java