Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><code>getNinePatchChunk</code> works just fine. It returned null because you were giving <code>Bitmap</code> a "source" ninepatch. It needs a "compiled" ninepatch image.</p> <p>There are two types of ninepatch file formats in the Android world ("source" and "compiled"). The source version is where you add the 1px transparency border everywhere-- when you compile your app into a .apk later, aapt will convert your *.9.png files to the binary format that Android expects. This is where the png file gets its "chunk" metadata. (<a href="https://ibotpeaches.github.io/Apktool/documentation/#9patch-images" rel="nofollow noreferrer">read more</a>)</p> <p>Okay, now down to business (you're listening to DJ kanzure).</p> <ol> <li><p>Client code, something like this:</p> <pre><code>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); </code></pre></li> <li><p>Server-side, you need to prepare your images. You can use the <a href="http://forum.xda-developers.com/showthread.php?t=785012" rel="nofollow noreferrer">Android Binary Resource Compiler</a>. This automates some of the pain away from creating a new Android project just to compile some *.9.png files into the Android native format. If you were to do this manually, you would essentially make a project and throw in some *.9.png files ("source" files), compile everything into the .apk format, unzip the .apk file, then find the *.9.png file, and that's the one you send to your clients.</p></li> </ol> <p>Also: I don't know if <code>BitmapFactory.decodeStream</code> knows about the npTc chunk in these png files, so it may or may not be treating the image stream correctly. The existence of <code>Bitmap.getNinePatchChunk</code> suggests that <code>BitmapFactory</code> might-- you could go look it up in the upstream codebase.</p> <p>In the event that it does not know about the npTc chunk and your images are being screwed up significantly, then my answer changes a little.</p> <p>Instead of sending the compiled ninepatch images to the client, you write a quick Android app to load compiled images and spit out the <code>byte[]</code> chunk. Then, you transmit this byte array to your clients along with a regular image-- no transparent borders, not the "source" ninepatch image, not the "compiled" ninepatch image. You can directly use the chunk to create your object.</p> <p>Another alternative is to use object serialization to send ninepatch images (<code>NinePatch</code>) to your clients, such as with JSON or the built-in serializer.</p> <p><strong>Edit</strong> If you really, really need to construct your own chunk byte array, I would start by looking at <code>do_9patch</code>, <code>isNinePatchChunk</code>, <code>Res_png_9patch</code> and <code>Res_png_9patch::serialize()</code> in ResourceTypes.cpp. There's also a home-made npTc chunk reader from Dmitry Skiba. I can't post links, so if someone can edit my answer that would be cool.</p> <p>do_9patch: <a href="https://android.googlesource.com/platform/frameworks/base/+/gingerbread/tools/aapt/Images.cpp" rel="nofollow noreferrer">https://android.googlesource.com/platform/frameworks/base/+/gingerbread/tools/aapt/Images.cpp</a></p> <p>isNinePatchChunk: <a href="http://netmite.com/android/mydroid/1.6/frameworks/base/core/jni/android/graphics/NinePatch.cpp" rel="nofollow noreferrer">http://netmite.com/android/mydroid/1.6/frameworks/base/core/jni/android/graphics/NinePatch.cpp</a></p> <p>struct Res_png_9patch: <a href="https://scm.sipfoundry.org/rep/sipX/main/sipXmediaLib/contrib/android/android_2_0_headers/frameworks/base/include/utils/ResourceTypes.h" rel="nofollow noreferrer">https://scm.sipfoundry.org/rep/sipX/main/sipXmediaLib/contrib/android/android_2_0_headers/frameworks/base/include/utils/ResourceTypes.h</a></p> <p>Dmitry Skiba stuff: <a href="http://code.google.com/p/android4me/source/browse/src/android/graphics/Bitmap.java" rel="nofollow noreferrer">http://code.google.com/p/android4me/source/browse/src/android/graphics/Bitmap.java</a></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. COThanks kanzure for a very impressive answer! I can't believe I didn't come to think of sending compiled images to the clients. I take it you haven't tried the solution with `BitmapFactory.decodeStream()` yourself, right!? Here's what I did: "compiled" the images with abrc and sent the compiled images to the client. I used `BitmapFactory.decodeStream()` to decode the compiled bitmaps, but nevertheless the `bitmap.getNinePatchChunk()` returns null. I tried it both on the emulator and on several targets (various API levels). Seems like `BitmapFactory` can't decode ninepatch images properly ... =(
      singulars
    2. COHmm. I was able to use `BitmapFactory.decodeStream()` successfully on a compiled ninepatch. Also, it successfully returned the chunk for me. Having said that, I don't know why I wrote my answer with that line about whether or not `decodeStream` knows about the chunk-- of course it does, otherwise my own attempts wouldn't have been working. But it does worry me that it isn't working for you. Can you confirm that your compiled ninepatches are indeed compiled? You can use `diff` to check if the before/afters are the same.
      singulars
    3. COYou're right! It's indeed possible to show "compiled" 9-patches by decoding them with `BitmapFactory.decodeStream()`! I got it working by setting up a small sample project that only retrieves a "compiled" 9-patch image over the network and displays it in the UI. It must be something else that messes up my original app. I use an image (disk) cache that could be the problem ... I'll have a look at it now! As soon as I found the cause, I'll let you know! Thanks, kanzure!
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload