Android开发之超强图片工具类BitmapUtil完整实例

Android开发之超强图片工具类BitmapUtil完整实例,第1张

概述本文实例讲述了Android开发之超强图片工具类BitmapUtil。分享给大家供大家参考,具体如下:

本文实例讲述了AndroID开发之超强图片工具类BitmapUtil。分享给大家供大家参考,具体如下:

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

使用了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<String,SoftReference<Bitmap>> imageCache = new HashMap<String,SoftReference<Bitmap>>(); /**  * 初始化lrucache,最少使用最先移除,LruCache来缓存图片,  * 当存储Image的大小大于LruCache设定的值,系统自动释放内存,  */ private static LruCache<String,Bitmap> mMemoryCache; static {  final int memory = (int) (Runtime.getRuntime().maxMemory() / 1024);  final int cacheSize = memory / 8;  mMemoryCache = new LruCache<String,Bitmap>(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<Integer,VoID,Bitmap> {  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<Bitmap> softBitmap = new SoftReference<Bitmap>(bitmap);  // 添加该对象到Map中使其缓存  imageCache.put(path,softBitmap); } public static Bitmap getBitmapByPath(String path) {  // 从缓存中取软引用的Bitmap对象  SoftReference<Bitmap> 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<Bitmap> 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>(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,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,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,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,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,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 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,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,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  */}

更多关于AndroID相关内容感兴趣的读者可查看本站专题:《Android图形与图像处理技巧总结》、《Android开发入门与进阶教程》、《Android调试技巧与常见问题解决方法汇总》、《Android基本组件用法总结》、《Android视图View技巧总结》、《Android布局layout技巧总结》及《Android控件用法总结》

希望本文所述对大家AndroID程序设计有所帮助。

总结

以上是内存溢出为你收集整理的Android开发之超强图片工具类BitmapUtil完整实例全部内容,希望文章能够帮你解决Android开发之超强图片工具类BitmapUtil完整实例所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1143814.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存