国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android開發之超強圖片工具類BitmapUtil完整實例

2019-10-22 18:23:50
字體:
來源:轉載
供稿:網友

本文實例講述了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, 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  */}

希望本文所述對大家Android程序設計有所幫助。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 云和县| 沂水县| 连云港市| 常宁市| 玛多县| 米林县| 永泰县| 中江县| 渭源县| 平山县| 满城县| 九江县| 敖汉旗| 丰原市| 武胜县| 武山县| 库车县| 凭祥市| 平潭县| 雷山县| 全椒县| 昭苏县| 乌拉特后旗| 酒泉市| 桓仁| 九龙城区| 阆中市| 新闻| 木兰县| 兰溪市| 兴海县| 甘南县| 禄劝| 芦山县| 泰来县| 蓬安县| 遵义市| 青海省| 应城市| 彭州市| 张掖市|