1
package com.example.util; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.media.ExifInterface; import android.os.Environment; import android.util.Log; import android.widget.Toast; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.ImageRequest; import com.example.volley.VolleyQueue; import com.will.main.WillApplication; /** * @author JL 一个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。 */ public class PhotoUtil { private static String tag = "PhotoUtil"; private final static String ALBUM_PATH = Environment .getExternalStorageDirectory() + "/Real/Image/"; /** * 读取图片属性:旋转的角度 * * @param path * 图片绝对路径 * @return degree旋转的角度 */ 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; } public static Bitmap rotaingImageView(int degree, Bitmap bm) { Bitmap returnBm = null; // 根据旋转角度,生成旋转矩阵 Matrix matrix = new Matrix(); matrix.postRotate(degree); try { // 将原始图片按照旋转矩阵进行旋转,并得到新的图片 returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); } catch (OutOfMemoryError e) { e.printStackTrace(); } if (returnBm == null) { returnBm = bm; } if (bm != returnBm) { bm.recycle(); } return returnBm; } // 缩放图片 public static Bitmap zoomImg(Bitmap bm, int newWidth, int newHeight) { // 获得图片的宽高 int width = bm.getWidth(); int height = bm.getHeight(); // 计算缩放比例 float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; // 取得想要缩放的matrix参数 Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); // 得到新的图片 Bitmap newbm = null; try { newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true); } catch (OutOfMemoryError e) { e.printStackTrace(); } if (newbm == null) { newbm = bm; } if (bm != newbm) { bm.recycle(); } return newbm; } /** * 根据宽来等比例约束图片的大小 * * @param path * @param width * @return */ public static BitmapFactory.Options getBitmapSize(String path) { BitmapFactory.Options options = new BitmapFactory.Options(); // 如果值设为true,那么将不返回实际的bitmap,也不给其分配内存空间,只去加载图片的外边缘,这样就避免了内存溢出。 options.inJustDecodeBounds = true; // 最终大小是1/inSampleSize // options.inSampleSize = 1; Bitmap bm = BitmapFactory.decodeFile(path, options); return options; } public static Bitmap decodebitmapByWidthWithRotate(String path, int widthPixels) { // TODO Auto-generated method stub int degree = PhotoUtil.readPictureDegree(path); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = false; Bitmap bitmap = null; try { bitmap = BitmapFactory.decodeFile(path, options); bitmap = PhotoUtil.rotaingImageView(degree, bitmap); } catch (OutOfMemoryError e) { e.printStackTrace(); } if (bitmap == null) { // 这里能出来,是因为options.inJustDecodeBounds = true; // 只是options被赋值了 return null; } float rate = (float) widthPixels / bitmap.getWidth(); Bitmap resizeBmp = Bitmap.createScaledBitmap(bitmap, widthPixels, (int) (rate * bitmap.getHeight()), true); bitmap.recycle(); return resizeBmp; } public static void saveImageByUrl(String imageUrl) { if (!Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { // new File(File dir, String name);在dir的目录下建一个name文件夹并返回 // getExternalCacheDir的路径是/sdcard/Android/data/<application // package>/cache Toast.makeText(WillApplication.getInstance(), "未找到sd卡", Toast.LENGTH_SHORT).show(); return; } ImageRequest imageRequest = new ImageRequest(imageUrl, new Response.Listener<Bitmap>() { @Override public void onResponse(Bitmap response) { saveImageByBitmap(response); } }, 0, 0, Config.RGB_565, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(WillApplication.getInstance(), "出错了,请稍后重试", Toast.LENGTH_SHORT).show(); } }); VolleyQueue.getInstance().add(imageRequest); } public static void saveImageByBitmap(Bitmap bitmap) { if (!Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { // new File(File dir, String name);在dir的目录下建一个name文件夹并返回 // getExternalCacheDir的路径是/sdcard/Android/data/<application // package>/cache Toast.makeText(WillApplication.getInstance(), "未找到sd卡", Toast.LENGTH_SHORT).show(); return; } FileOutputStream fileOutputStream = null; try { File dirFile = new File(ALBUM_PATH); if (!dirFile.exists()) { dirFile.mkdirs(); } File imageFile = new File(dirFile, bitmap.hashCode() + ".jpg"); if (!imageFile.exists()) { imageFile.createNewFile(); // 新建文件 } fileOutputStream = new FileOutputStream(imageFile); bitmap.compress(Bitmap.CompressFormat.JPEG, 60, fileOutputStream); Log.i(tag, imageFile.getName()); Toast.makeText(WillApplication.getInstance(), "图片保存至/sdcard/Real/Image" + imageFile.getName(), Toast.LENGTH_SHORT).show(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { if (fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } if (bitmap.isRecycled()) { bitmap.recycle(); } } catch (Exception e) { e.printStackTrace(); } } } }
Done!
时间: 2024-10-12 17:26:26