package com.nd.sdp.android.common.skinmanager.external; import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.lang.reflect.Field; import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Color;import android.graphics.NinePatch;import android.graphics.Rect;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.graphics.drawable.NinePatchDrawable; /***  *   * @author Administrator  *  */public class NinePatchUtils { private final static int NO_COLOR = 0x00000001;private NinePatchUtils() { }/*** * 读取assets下图片,此处修改了NinePatchDrawable不能正常读取问题, * e.g * Drawable bg = NinePatchTool.decodeDrawableFromAsset(this, path); *  * assetPath:如果存在子目录,则需要写子目录名称,如下:"aaa/log.png" * @param context * @param assetPath * @return * @throws Exception */public static Drawable decodeDrawableFromAsset(Context context,String assetPath) throws Exception {Bitmap bitmap = readFromAsset(context, assetPath);if (bitmap.getNinePatchChunk() == null) {return new BitmapDrawable(bitmap);} else {Rect paddingRect = new Rect();readPaddingFromChunk(bitmap.getNinePatchChunk(), paddingRect);return new NinePatchDrawable(context.getResources(),bitmap, bitmap.getNinePatchChunk(), paddingRect, null);}} public static Drawable decodeDrawableFromFile(String filePath) throws Exception { Bitmap bitmap = decodeFromFile(filePath); if (bitmap.getNinePatchChunk() == null) { return new BitmapDrawable(bitmap); } else { Rect paddingRect = new Rect(); readPaddingFromChunk(bitmap.getNinePatchChunk(), paddingRect); return new NinePatchDrawable(bitmap, bitmap.getNinePatchChunk(), paddingRect, null); } }/*** * 通过流读取图片 * @param in * @return * @throws Exception */public static Bitmap decodeFromStream(InputStream in) throws Exception {Bitmap srcBm = BitmapFactory.decodeStream(in);byte[] chunk = readChunk(srcBm);boolean isNinePatchChunk = NinePatch.isNinePatchChunk(chunk);if (isNinePatchChunk) {Bitmap tgtBm = Bitmap.createBitmap(srcBm, 1, 1,srcBm.getWidth() - 2, srcBm.getHeight() - 2);srcBm.recycle();Field f = tgtBm.getClass().getDeclaredField("mNinePatchChunk");f.setAccessible(true);f.set(tgtBm, chunk);return tgtBm;} else {return srcBm;}}/*** * 通过制定目录读取文件 * @param path * @return * @throws Exception */public static Bitmap decodeFromFile(String path) throws Exception {InputStream in = new FileInputStream(path);Bitmap bm = decodeFromStream(in);in.close();return bm;}/*** * 读取Assets下图片包括.9.png * @param context * @param ninePatchPngPath * @return * @throws Exception */public static Bitmap readFromAsset(Context context,String ninePatchPngPath) throws Exception {InputStream is = context.getAssets().open(ninePatchPngPath);Bitmap bm = decodeFromStream(is);is.close();return bm;} public static void readPaddingFromChunk(byte[] chunk, Rect paddingRect) {paddingRect.left = getInt(chunk, 12);paddingRect.right = getInt(chunk, 16);paddingRect.top = getInt(chunk, 20);paddingRect.bottom = getInt(chunk, 24);} public static byte[] readChunk(Bitmap resourceBmp) throws IOException {final int BM_W = resourceBmp.getWidth();final int BM_H = resourceBmp.getHeight(); int xPointCount = 0;int yPointCount = 0;int xBlockCount = 0;int yBlockCount = 0; ByteArrayOutputStream bao = new ByteArrayOutputStream();for (int i = 0; i < 32; i++) {bao.write(0);} {int[] pixelsTop = new int[BM_W - 2];resourceBmp.getPixels(pixelsTop, 0, BM_W, 1, 0, BM_W - 2, 1);boolean topFirstPixelIsBlack = pixelsTop[0] == Color.BLACK;boolean topLastPixelIsBlack = pixelsTop[pixelsTop.length - 1] == Color.BLACK;int tmpLastColor = Color.TRANSPARENT;for (int i = 0, len = pixelsTop.length; i < len; i++) {if (tmpLastColor != pixelsTop[i]) {xPointCount++;writeInt(bao, i);tmpLastColor = pixelsTop[i];}}if (topLastPixelIsBlack) {xPointCount++;writeInt(bao, pixelsTop.length);}xBlockCount = xPointCount + 1;if (topFirstPixelIsBlack) {xBlockCount--;}if (topLastPixelIsBlack) {xBlockCount--;}} {int[] pixelsLeft = new int[BM_H - 2];resourceBmp.getPixels(pixelsLeft, 0, 1, 0, 1, 1, BM_H - 2);boolean firstPixelIsBlack = pixelsLeft[0] == Color.BLACK;boolean lastPixelIsBlack = pixelsLeft[pixelsLeft.length - 1] == Color.BLACK;int tmpLastColor = Color.TRANSPARENT;for (int i = 0, len = pixelsLeft.length; i < len; i++) {if (tmpLastColor != pixelsLeft[i]) {yPointCount++;writeInt(bao, i);tmpLastColor = pixelsLeft[i];}}if (lastPixelIsBlack) {yPointCount++;writeInt(bao, pixelsLeft.length);}yBlockCount = yPointCount + 1;if (firstPixelIsBlack) {yBlockCount--;}if (lastPixelIsBlack) {yBlockCount--;}} {for (int i = 0; i < xBlockCount * yBlockCount; i++) {writeInt(bao, NO_COLOR);}} byte[] data = bao.toByteArray();data[0] = 1;data[1] = (byte) xPointCount;data[2] = (byte) yPointCount;data[3] = (byte) (xBlockCount * yBlockCount);dealPaddingInfo(resourceBmp, data);return data;} private static void dealPaddingInfo(Bitmap bm, byte[] data) {{ // padding left & padding rightint[] bottomPixels = new int[bm.getWidth() - 2];bm.getPixels(bottomPixels, 0, bottomPixels.length, 1,bm.getHeight() - 1, bottomPixels.length, 1);for (int i = 0; i < bottomPixels.length; i++) {if (Color.BLACK == bottomPixels[i]) { // padding leftwriteInt(data, 12, i);break;}}for (int i = bottomPixels.length - 1; i >= 0; i--) {if (Color.BLACK == bottomPixels[i]) { // padding rightwriteInt(data, 16, bottomPixels.length - i - 2);break;}}}{ // padding top & padding bottomint[] rightPixels = new int[bm.getHeight() - 2];bm.getPixels(rightPixels, 0, 1, bm.getWidth() - 1, 0, 1,rightPixels.length);for (int i = 0; i < rightPixels.length; i++) {if (Color.BLACK == rightPixels[i]) { // padding topwriteInt(data, 20, i);break;}}for (int i = rightPixels.length - 1; i >= 0; i--) {if (Color.BLACK == rightPixels[i]) { // padding bottomwriteInt(data, 24, rightPixels.length - i - 2);break;}}}} private static void writeInt(OutputStream out, int v) throws IOException {out.write((v >> 0) & 0xFF);out.write((v >> 8) & 0xFF);out.write((v >> 16) & 0xFF);out.write((v >> 24) & 0xFF);} private static void writeInt(byte[] b, int offset, int v) {b[offset + 0] = (byte) (v >> 0);b[offset + 1] = (byte) (v >> 8);b[offset + 2] = (byte) (v >> 16);b[offset + 3] = (byte) (v >> 24);} private static int getInt(byte[] bs, int from) {int b1 = bs[from + 0];int b2 = bs[from + 1];int b3 = bs[from + 2];int b4 = bs[from + 3];int i = b1 | (b2 << 8)  | (b3 << 16) | b4 << 24;return i;} /** print chunk info from bitmap */public static void printChunkInfo(Bitmap bm) {byte[] chunk = bm.getNinePatchChunk();if (null == chunk) {System.out.println("can't find chunk info from this bitmap(" + bm+ ")");return;}int xLen = chunk[1];int yLen = chunk[2];int cLen = chunk[3]; StringBuilder sb = new StringBuilder();int peddingLeft = getInt(chunk, 12);int paddingRight = getInt(chunk, 16);int paddingTop = getInt(chunk, 20);int paddingBottom = getInt(chunk, 24);sb.append("peddingLeft=" + peddingLeft);sb.append("\r\n");sb.append("paddingRight=" + paddingRight);sb.append("\r\n");sb.append("paddingTop=" + paddingTop);sb.append("\r\n");sb.append("paddingBottom=" + paddingBottom);sb.append("\r\n"); sb.append("x info=");for (int i = 0; i < xLen; i++) {int vv = getInt(chunk, 32 + i * 4);sb.append("," + vv);}sb.append("\r\n");sb.append("y info=");for (int i = 0; i < yLen; i++) {int vv = getInt(chunk, xLen * 4 + 32 + i * 4);sb.append("," + vv);}sb.append("\r\n");sb.append("color info=");for (int i = 0; i < cLen; i++) {int vv = getInt(chunk, xLen * 4 + yLen * 4 + 32 + i * 4);sb.append("," + vv);}System.err.println("" + sb);}}

更多相关文章

  1. andriod之ContentProvider读取外部存储图片
  2. 自定义 照相机
  3. Android(安卓)监听开机完成广播,完成监听SIM卡功能
  4. 一个图片制作ProgressBar
  5. gridview显示图片
  6. Android(安卓)Bitmap详细介绍
  7. android 设置圆角图片实现代码
  8. x、Android保存图片至相册原生代码
  9. 使用AnsyncTask异步类从网络上下载图片

随机推荐

  1. [Android]实现点击持续录音,松开结束录音,
  2. android中如何发送短信、接收短信
  3. Android(安卓)DataBinding 基础使用
  4. android 垂直方向上下滑动阻尼效果
  5. android音量设置from top to bottom
  6. android拍照压缩及添加水印3
  7. android 屏幕分辨率与密度,dip与px的区别(
  8. Android(安卓)studio或者idea: marketplac
  9. Android(安卓)中GridView上图下字、GridV
  10. Android基于Intent实现Activity之间数据