说明:为了方便大家使用,本人把大家常用的图片处理代码集中到这个类里
使用了LruCache与SoftReference

/** * 图片加载及转化工具 ----------------------------------------------------------------------- 延伸:一个Bitmap到底占用多大内存?系统给每个应用程序分配多大内存? Bitmap占用的内存为:像素总数 * * 每个像素占用的内存。在Android中, Bitmap有四种像素类型:ARGB_8888、ARGB_4444、ARGB_565、ALPHA_8, 他们每个像素占用的字节数分别为4、2、2、1。因此,一个2000*1000的ARGB_8888 * 类型的Bitmap占用的内存为2000*1000*4=8000000B=8MB。 *  * @author chen.lin * */public class BitmapUtil {    /**     *   1)软引用 ,已经不适合缓存图片信息,加载图片时会出现重叠的现象     *   2)Android 3.0 (API Level 11)中,图片的数据会存储在本地的内存当中     *   因而无法用一种可预见的方式将其释放,这就有潜在的风险造成应用程序的内存溢出并崩溃,     *   3)因为从 Android 2.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,            这让软引用和弱引用变得不再可靠。     *        */    private static Map> imageCache = new HashMap>();    /**     *  初始化lrucache,最少使用最先移除,LruCache来缓存图片,     *  当存储Image的大小大于LruCache设定的值,系统自动释放内存,     */    private static LruCache mMemoryCache;    static {        final int memory = (int) (Runtime.getRuntime().maxMemory() / 1024);        final int cacheSize = memory / 8;        mMemoryCache = new LruCache(cacheSize) {            protected int sizeOf(String key, Bitmap value) {                // return value.getByteCount() / 1024;                return value.getHeight() * value.getRowBytes();            }        };    }    // ---lrucache----------------------------------------------------    /**     * 添加图片到lrucache     *      * @param key     * @param bitmap     */    public synchronized void addBitmapToMemCache(String key, Bitmap bitmap) {        if (getBitmapFromMemCache(key) == null) {            if (key != null & bitmap != null) {                mMemoryCache.put(key, bitmap);            }        }    }    /**     * 清除缓存     */    public void clearMemCache() {        if (mMemoryCache != null) {            if (mMemoryCache.size() > 0) {                mMemoryCache.evictAll();            }            mMemoryCache = null;        }    }    /**     * 移除缓存     */    public synchronized void removeMemCache(String key) {        if (key != null) {            if (mMemoryCache != null) {                Bitmap bm = mMemoryCache.remove(key);                if (bm != null)                    bm.recycle();            }        }    }    /**     * 从lrucache里读取图片     *      * @param key     * @return     */    public Bitmap getBitmapFromMemCache(String key) {        if (key != null) {            return mMemoryCache.get(key);        }        return null;    }    /**     * 加载图片     *      * @param context     * @param resId     * @param imageView     */    public void loadBitmap(Context context, int resId, ImageView imageView) {        final String imageKey = String.valueOf(resId);        final Bitmap bitmap = getBitmapFromMemCache(imageKey);        if (bitmap != null) {            imageView.setImageBitmap(bitmap);        } else {            imageView.setImageResource(resId);            BitmapWorkerTask task = new BitmapWorkerTask(context);            task.execute(resId);        }    }    /**     * 任务类     *      * @Project App_View     * @Package com.android.view.tool     * @author chenlin     * @version 1.0     * @Date 2014年5月10日     */    class BitmapWorkerTask extends AsyncTask {        private Context mContext;        public BitmapWorkerTask(Context context) {            mContext = context;        }        // 在后台加载图片。        @Override        protected Bitmap doInBackground(Integer... params) {            final Bitmap bitmap = decodeSampledBitmapFromResource(mContext.getResources(), params[0], 100, 100);            addBitmapToMemCache(String.valueOf(params[0]), bitmap);            return bitmap;        }    }    // --软引用---------------------------------------------------------    public static void addBitmapToCache(String path) {        // 强引用的Bitmap对象        Bitmap bitmap = BitmapFactory.decodeFile(path);        // 软引用的Bitmap对象        SoftReference softBitmap = new SoftReference(bitmap);        // 添加该对象到Map中使其缓存        imageCache.put(path, softBitmap);    }    public static Bitmap getBitmapByPath(String path) {        // 从缓存中取软引用的Bitmap对象        SoftReference softBitmap = imageCache.get(path);        // 判断是否存在软引用        if (softBitmap == null) {            return null;        }        // 取出Bitmap对象,如果由于内存不足Bitmap被回收,将取得空        Bitmap bitmap = softBitmap.get();        return bitmap;    }    public Bitmap loadBitmap(final String imageUrl, final ImageCallBack imageCallBack) {        SoftReference reference = imageCache.get(imageUrl);        if (reference != null) {            if (reference.get() != null) {                return reference.get();            }        }        final Handler handler = new Handler() {            public void handleMessage(final android.os.Message msg) {                // 加入到缓存中                Bitmap bitmap = (Bitmap) msg.obj;                imageCache.put(imageUrl, new SoftReference(bitmap));                if (imageCallBack != null) {                    imageCallBack.getBitmap(bitmap);                }            }        };        new Thread() {            public void run() {                Message message = handler.obtainMessage();                message.obj = downloadBitmap(imageUrl);                handler.sendMessage(message);            }        }.start();        return null;    }    public interface ImageCallBack {        void getBitmap(Bitmap bitmap);    }    // ----其它工具----------------------------------------------------------------------------------    /**     * 从网上下载图片     *      * @param imageUrl     * @return     */    private Bitmap downloadBitmap(String imageUrl) {        Bitmap bitmap = null;        try {            bitmap = BitmapFactory.decodeStream(new URL(imageUrl).openStream());            return bitmap;        } catch (Exception e) {            e.printStackTrace();            return null;        }    }    /**     * drawable 转bitmap     *      * @param drawable     * @return     */    public static Bitmap drawable2Bitmap(Drawable drawable) {        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),                drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);        Canvas canvas = new Canvas(bitmap);        // canvas.setBitmap(bitmap);        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());        drawable.draw(canvas);        return bitmap;    }    /**     * bitmap 转 drawable     *      * @param bm     * @return     */    public static Drawable bitmap2Drable(Bitmap bm) {        return new BitmapDrawable(bm);    }    /**     * 把字节数组通过BASE64Encoder转换成字符串     *      * @param image     * @return     */    public static String getBase64(byte[] image) {        String string = "";        try {            BASE64Encoder encoder = new BASE64Encoder();            string = encoder.encodeBuffer(image).trim();        } catch (Exception e) {            e.printStackTrace();        }        return string;    }    /**     * 把字节数据转换成Drawable     *      * @param imgByte     *            字节数据     * @return     */    @SuppressWarnings("deprecation")    public static Drawable byte2Drawable(byte[] imgByte) {        Bitmap bitmap;        if (imgByte != null) {            bitmap = BitmapFactory.decodeByteArray(imgByte, 0, imgByte.length);            Drawable drawable = new BitmapDrawable(bitmap);            return drawable;        }        return null;    }    /**     * 把图片转换成字节数组     *      * @param bmp     * @return     */    public static byte[] bitmap2Byte(Bitmap bm) {        Bitmap outBitmap = Bitmap.createScaledBitmap(bm, 150, bm.getHeight() * 150 / bm.getWidth(), true);        if (bm != outBitmap) {            bm.recycle();            bm = null;        }        byte[] compressData = null;        ByteArrayOutputStream baos = new ByteArrayOutputStream();        try {            try {                outBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);            } catch (Exception e) {                e.printStackTrace();            }            compressData = baos.toByteArray();            baos.close();        } catch (IOException e) {            e.printStackTrace();        }        return compressData;    }    /**     * 缩放图片     *      * @param bitmap     *            原图片     * @param newWidth     * @param newHeight     * @return     */    public static Bitmap setBitmapSize(Bitmap bitmap, int newWidth, int newHeight) {        int width = bitmap.getWidth();        int height = bitmap.getHeight();        float scaleWidth = (newWidth * 1.0f) / width;        float scaleHeight = (newHeight * 1.0f) / height;        Matrix matrix = new Matrix();        matrix.postScale(scaleWidth, scaleHeight);        return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);    }    /**     * 缩放图片     *      * @param bitmapPath     *            图片路径     * @return     */    public static Bitmap setBitmapSize(String bitmapPath, float newWidth, float newHeight) {        Bitmap bitmap = BitmapFactory.decodeFile(bitmapPath);        if (bitmap == null) {            Logger.i("bitmap", "bitmap------------>发生未知异常!");            return null;        }        int width = bitmap.getWidth();        int height = bitmap.getHeight();        float scaleWidth = newWidth / width;        float scaleHeight = newHeight / height;        Matrix matrix = new Matrix();        matrix.postScale(scaleWidth, scaleHeight);        return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);    }    /**     * 计算图片的缩放大小 如果==1,表示没变化,==2,表示宽高都缩小一倍 ----------------------------------------------------------------------------     * inSampleSize是BitmapFactory.Options类的一个参数,该参数为int型, 他的值指示了在解析图片为Bitmap时在长宽两个方向上像素缩小的倍数。inSampleSize的默认值和最小值为1(当小于1时,解码器将该值当做1来处理),     * 且在大于1时,该值只能为2的幂(当不为2的幂时,解码器会取与该值最接近的2的幂)。 例如,当inSampleSize为2时,一个2000*1000的图片,将被缩小为1000*500,相应地, 它的像素数和内存占用都被缩小为了原来的1/4:     *      * @param options     * @param reqWidth     * @param reqHeight     * @return     */    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {        // 原始图片的宽高        final int height = options.outHeight;        final int width = options.outWidth;        int inSampleSize = 1;        if (height > reqHeight || width > reqWidth) {            final int halfHeight = height / 2;            final int halfWidth = width / 2;            // 在保证解析出的bitmap宽高分别大于目标尺寸宽高的前提下,取可能的inSampleSize的最大值            while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {                inSampleSize *= 2;            }        }        return inSampleSize;    }    /**     * 根据计算出的inSampleSize生成Bitmap(此时的bitmap是经过缩放的图片)     *      * @param res     * @param resId     * @param reqWidth     * @param reqHeight     * @return     */    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {        // 首先设置 inJustDecodeBounds=true 来获取图片尺寸        final BitmapFactory.Options options = new BitmapFactory.Options();        /**         * inJustDecodeBounds属性设置为true,decodeResource()方法就不会生成Bitmap对象,而仅仅是读取该图片的尺寸和类型信息:         */        options.inJustDecodeBounds = true;        BitmapFactory.decodeResource(res, resId, options);        // 计算 inSampleSize 的值        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);        // 根据计算出的 inSampleSize 来解码图片生成Bitmap        options.inJustDecodeBounds = false;        return BitmapFactory.decodeResource(res, resId, options);    }    /**     * 将图片保存到本地时进行压缩, 即将图片从Bitmap形式变为File形式时进行压缩,      * 特点是: File形式的图片确实被压缩了, 但是当你重新读取压缩后的file为 Bitmap是,它占用的内存并没有改变     *      * @param bmp     * @param file     */    public static void compressBmpToFile(Bitmap bmp, File file) {        ByteArrayOutputStream baos = new ByteArrayOutputStream();        int options = 80;// 个人喜欢从80开始,        bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);        while (baos.toByteArray().length / 1024 > 100) {            baos.reset();            options -= 10;            bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);        }        try {            FileOutputStream fos = new FileOutputStream(file);            fos.write(baos.toByteArray());            fos.flush();            fos.close();        } catch (Exception e) {            e.printStackTrace();        }    }    /**     *  将图片从本地读到内存时,进行压缩 ,即图片从File形式变为Bitmap形式     *  特点: 通过设置采样率, 减少图片的像素, 达到对内存中的Bitmap进行压缩     * @param srcPath     * @return     */    public static Bitmap compressImageFromFile(String srcPath, float pixWidth, float pixHeight) {        BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = true;// 只读边,不读内容        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, options);        options.inJustDecodeBounds = false;        int w = options.outWidth;        int h = options.outHeight;        int scale = 1;        if (w > h && w > pixWidth) {            scale = (int) (options.outWidth / pixWidth);        } else if (w < h && h > pixHeight) {            scale = (int) (options.outHeight / pixHeight);        }        if (scale <= 0)            scale = 1;        options.inSampleSize = scale;// 设置采样率        options.inPreferredConfig = Config.ARGB_8888;// 该模式是默认的,可不设        options.inPurgeable = true;// 同时设置才会有效        options.inInputShareable = true;// 。当系统内存不够时候图片自动被回收        bitmap = BitmapFactory.decodeFile(srcPath, options);        // return compressBmpFromBmp(bitmap);//原来的方法调用了这个方法企图进行二次压缩        // 其实是无效的,大家尽管尝试        return bitmap;    }    /**     * 判断照片的角度     * @param path     * @return     */    public static int readPictureDegree(String path) {          int degree = 0;          try {              ExifInterface exifInterface = new ExifInterface(path);              int orientation = exifInterface.getAttributeInt(                      ExifInterface.TAG_ORIENTATION,                      ExifInterface.ORIENTATION_NORMAL);              switch (orientation) {              case ExifInterface.ORIENTATION_ROTATE_90:                  degree = 90;                  break;              case ExifInterface.ORIENTATION_ROTATE_180:                  degree = 180;                  break;              case ExifInterface.ORIENTATION_ROTATE_270:                  degree = 270;                  break;              }          } catch (IOException e) {              e.printStackTrace();          }          return degree;      }      /**     * Android根据设备屏幕尺寸和dpi的不同,给系统分配的单应用程序内存大小也不同,具体如下表     *      * 屏幕尺寸 DPI 应用内存      * small / normal / large ldpi / mdpi 16MB      * small / normal / large tvdpi / hdpi 32MB      * small / normal / large xhdpi 64MB     * small / normal / large 400dpi 96MB      * small / normal / large xxhdpi 128MB      * -------------------------------------------------------      * xlarge mdpi 32MB      * xlarge tvdpi / hdpi 64MB      * xlarge xhdpi 128MB      * xlarge 400dpi 192MB      * xlarge xxhdpi 256MB     */}

———————————————————————
有需求者请加qq:136137465,非诚勿扰
(java 架构师全套教程,共760G, 让你从零到架构师,每月轻松拿3万)
01.高级架构师四十二个阶段高
02.Java高级系统培训架构课程148课时
03.Java高级互联网架构师课程
04.Java互联网架构Netty、Nio、Mina等-视频教程
05.Java高级架构设计2016整理-视频教程
06.架构师基础、高级片
07.Java架构师必修linux运维系列课程
08.Java高级系统培训架构课程116课时
(送:hadoop系列教程,java设计模式与数据结构, Spring Cloud微服务, SpringBoot入门)
——————————————————————–

更多相关文章

  1. Android(安卓)引用使用外部字体
  2. Android高仿微信相册选择器 多图片选择器、拍照
  3. Picasso的使用
  4. 使用MAT分析应用的内存信息
  5. Android文字图片写入CSV(Base64)并分享
  6. Drawable(hdpi,ldpi,mdpi)目录的区别
  7. Android屏幕图标尺寸规范
  8. Android桌面悬浮清内存app概述
  9. Android系统移植与调试之------->如何修改Android启动动画和开机

随机推荐

  1. 就等android了
  2. Android深入浅出之Audio(1,2,3)
  3. Android(安卓)开发环境搭建
  4. ANDROID导入文件后的本地无法编译生成R.j
  5. Android事件分发机制完全解析
  6. Android中ListView 控件与 Adapter 适配
  7. Android 横竖屏操作
  8. Android(安卓)适配toolbar后windowSoftIn
  9. Android(安卓)studio 生成的fragment_mai
  10. android 使用intent传递参数实现乘法计算