获得清晰且占用native内存很小的bitmap
	 
	import java.io.ByteArrayOutputStream;
	import java.io.File;
	import java.io.FileDescriptor;
	import java.io.FileInputStream;
	import java.io.IOException;
	import java.io.InputStream;
	
	import android.content.res.Resources;
	import android.graphics.Bitmap;
	import android.graphics.BitmapFactory;
	import android.util.Log;
	
	/**
	 * 图片采样,获得清晰且占用内存很小的bitmap(Bitmap对象由Native方法生成) 。类说明 : 图片大小修改 避免oom内存溢出;
	 * 暂时使用的方法都采用 decodeSampledBitmapFromPathMoreSafe(),后期需要用到其他方法,
	 * 按照decodeSampledBitmapFromPathMoreSafe重新修改,测试通过后在此记录,并更新备份此代码。 已修改代码:1、Bitmap
	 * decodeSampledBitmapFromPath(String path, int reqWidth, int reqHeight);
	 * 
	 * @version 创建时间:2016年7月14日 下午1:45:06
	 * 
	 */
	public class ImageResizer {
	    private static final String TAG = "ImageResizer";
	
	    public ImageResizer() {
	    }
	
	    // 传入资源文件,计算合适的大小,返回一个Bitmap对象
	    public Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
	            int reqWidth, int reqHeight) {
	        // First decode with inJustDecodeBounds=true to check dimensions
	        final BitmapFactory.Options options = new BitmapFactory.Options();
	        options.inJustDecodeBounds = true;
	        BitmapFactory.decodeResource(res, resId, options);
	
	        // Calculate inSampleSize
	        options.inSampleSize = calculateInSampleSize(options, reqWidth,
	                reqHeight);
	
	        // Decode bitmap with inSampleSize set
	        options.inJustDecodeBounds = false;
	        return BitmapFactory.decodeResource(res, resId, options);// 或者其他方式
	
	    }
	
	    /**
	     * 为了加载文件系统的文件避免二次decodeStream返回null而专门调整的方法decode方法 解释:
	     * FileInputStream是一种有序的文件流,而两次的decodeStream调用影响了文件流的位置属性,
	     * 导致了第二次decodeStream时得到的是null,为了解决这个问题,可以通过文件流来得到他所对应的文件描述符, 然后在通过
	     * BitmapFactory.decodeFileDescriptor方法来加载一张缩放过的图片
	     */
	    public Bitmap decodeSampledBitmapFromFileDescriptor(FileDescriptor fd,
	            int reqWidth, int reqHeight) {
	        // First decode with inJustDecodeBounds=true to check dimensions
	        final BitmapFactory.Options options = new BitmapFactory.Options();
	
	        options.inJustDecodeBounds = true;
	        BitmapFactory.decodeFileDescriptor(fd, null, options);
	
	        // Calculate inSampleSize
	        options.inSampleSize = calculateInSampleSize(options, reqWidth,
	                reqHeight);
	
	        // Decode bitmap with inSampleSize set
	        options.inJustDecodeBounds = false;
	        return BitmapFactory.decodeFileDescriptor(fd, null, options);
	    }
	
	    /**
	     * 方法说明:可能还是解决不了内存溢出,最多捕获内存溢出。使用decodeSampledBitmapFromPathMoreSafe处理
	     */
	    @Deprecated
	    public Bitmap decodeSampledBitmapFromPath(String path, int reqWidth,
	            int reqHeight) {
	        // First decode with inJustDecodeBounds=true to check dimensions
	        final BitmapFactory.Options options = new BitmapFactory.Options();
	        options.inJustDecodeBounds = true;
	        BitmapFactory.decodeFile(path, options);
	
	        // Calculate inSampleSize
	        options.inSampleSize = calculateInSampleSize(options, reqWidth,
	                reqHeight);
	
	        // Decode bitmap with inSampleSize set
	        options.inJustDecodeBounds = false;
	        try {
	            return BitmapFactory.decodeFile(path, options);
	        } catch (OutOfMemoryError e) {
	            e.printStackTrace();
	        }
	        return null;
	    }
	
	    /**
	     * 20160918新增:inSampleSize 重新计算(之前的方法计算的值不够精确),并捕获异常。
	     * if(!bmp.isRecycle() ){ bmp.recycle() //回收图片所占的内存 system.gc() //提醒系统及时回收 }
	     * 从ImageView中获取
	     */
	    public Bitmap decodeSampledBitmapFromPathMoreSafe(String path,
	            int reqWidth, int reqHeight) {
	        final BitmapFactory.Options options = new BitmapFactory.Options();
	        options.inDither = false;
	        options.inPurgeable = true;
	        options.inTempStorage = new byte[12 * 1024];// 创建一个12kb的临时空间
	        options.inJustDecodeBounds = true;
	
	        File file = new File(path);
	        FileInputStream fs = null;
	        try {
	            fs = new FileInputStream(file);
	
	            BitmapFactory.decodeFileDescriptor(fs.getFD(), null, options);
	        } catch (Exception e1) {
	            // TODO Auto-generated catch block
	            e1.printStackTrace();
	        }
	        // Calculate inSampleSize
	        // options.inSampleSize = calculateInSampleSize(options, reqWidth,
	        // reqHeight);
	        /**
	         * 使用此方法计算inSampleSize值 20160918新增
	         */
	        final int minSideLength = Math.min(reqWidth, reqHeight);
	        options.inSampleSize = computeSampleSize(options, minSideLength,
	                reqWidth * reqHeight);
	        // Decode bitmap with inSampleSize set
	        options.inJustDecodeBounds = false;
	
	        Bitmap bmp = null;
	        try {
	            fs = new FileInputStream(file);
	            if (fs != null)
	                bmp = BitmapFactory.decodeFileDescriptor(fs.getFD(), null,
	                        options);
	            if (fs != null) {
	                fs.close();
	                fs = null;
	            }
	            return bmp;
	
	        } catch (Exception e) {
	
	            try {
	                if (fs != null) {
	                    fs.close();
	                    fs = null;
	                }
	            } catch (IOException e1) {
	                e1.printStackTrace();
	            }
	            Log.i("test",
	                    "ImageResizer(图片压缩) decodeSampledBitmapFromPathMoreSafe 出现内存溢出 并返回null对象");
	            e.printStackTrace();
	        }
	        return null;
	    }
	
	    /**
	     * 方法说明: 直接使用 BitmapFactory.decodeStream(is) 返回空
	     * 
	     * @version 创建时间:2016年8月16日 下午6:14:26
	     * 
	     * @param is
	     * @param reqWidth
	     * @param reqHeight
	     * @return
	     */
	    public Bitmap decodeSampledBitmapFromInputStream(InputStream is,
	            int reqWidth, int reqHeight) {
	        // First decode with inJustDecodeBounds=true to check dimensions
	        Log.i("test", "decodeStream is0 == null " + String.valueOf(is == null));
	        byte[] data = null;
	        try {
	            data = readStream(is);
	        } catch (Exception e) {
	            // TODO Auto-generated catch block
	            e.printStackTrace();
	        }
	
	        final BitmapFactory.Options options = new BitmapFactory.Options();
	        options.inJustDecodeBounds = true;
	        BitmapFactory.decodeByteArray(data, 0, data.length, options);
	        // Calculate inSampleSize
	        options.inSampleSize = calculateInSampleSize(options, reqWidth,
	                reqHeight);
	
	        // Decode bitmap with inSampleSize set
	        options.inJustDecodeBounds = false;
	
	        Bitmap decodeStream = BitmapFactory.decodeByteArray(data, 0,
	                data.length, options);
	        Log.i("test",
	                "decodeStream Bitmap == null "
	                        + String.valueOf(decodeStream == null));
	        Log.i("test", "decodeStream is1 == null " + String.valueOf(is == null));
	        Log.i("test", "decodeStream Bitmap size " + decodeStream.getByteCount());
	        Log.i("test", "decodeStream options.inSampleSize = "
	                + options.inSampleSize);
	
	        return decodeStream;
	
	    }
	
	    /**
	     * 原始方法计算的inSampleSize值不够精确,容易导致oom
	     */
	    public int calculateInSampleSize(BitmapFactory.Options options,
	            int reqWidth, int reqHeight) {
	        if (reqWidth == 0 || reqHeight == 0) {
	            return 1;
	        }
	
	        // Raw height and width of image
	        final int height = options.outHeight;
	        final int width = options.outWidth;
	        Log.d(TAG, "origin, w= " + width + " h=" + height);
	        int inSampleSize = 1;
	
	        if (height > reqHeight || width > reqWidth) {
	            final int halfHeight = height / 2;
	            final int halfWidth = width / 2;
	
	            // Calculate the largest inSampleSize value that is a power of 2 and
	            // keeps both
	            // height and width larger than the requested height and width.
	            while ((halfHeight / inSampleSize) >= reqHeight
	                    && (halfWidth / inSampleSize) >= reqWidth) {
	                inSampleSize *= 2;
	            }
	        }
	
	        Log.d(TAG, "sampleSize:" + inSampleSize);
	        return inSampleSize;
	    }
	
	    public static int computeSampleSize(BitmapFactory.Options options,
	            int minSideLength, int maxNumOfPixels) {
	        int initialSize = computeInitialSampleSize(options, minSideLength,
	                maxNumOfPixels);
	        int roundedSize;
	        if (initialSize <= 8) {
	            roundedSize = 1;
	            while (roundedSize < initialSize) {
	                roundedSize <<= 1;
	            }
	        } else {
	            roundedSize = (initialSize + 7) / 8 * 8;
	        }
	
	        return roundedSize;
	    }
	
	    private static int computeInitialSampleSize(BitmapFactory.Options options,
	            int minSideLength, int maxNumOfPixels) {
	        double w = options.outWidth;
	        double h = options.outHeight;
	
	        int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math
	                .sqrt(w * h / maxNumOfPixels));
	        int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(
	                Math.floor(w / minSideLength), Math.floor(h / minSideLength));
	
	        if (upperBound < lowerBound) {
	            // return the larger one when there is no overlapping zone.
	            return lowerBound;
	        }
	
	        if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
	            return 1;
	        } else if (minSideLength == -1) {
	            return lowerBound;
	        } else {
	            return upperBound;
	        }
	    }
	
	    /*
	     * 得到图片字节流 数组大小
	     */
	    public static byte[] readStream(InputStream inStream) throws Exception {
	        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
	        byte[] buffer = new byte[1024];
	        int len = 0;
	        while ((len = inStream.read(buffer)) != -1) {
	            outStream.write(buffer, 0, len);
	        }
	        outStream.close();
	        inStream.close();
	        return outStream.toByteArray();
	    }
	}