android 压缩图片大小,防止OOM
android开发中,图片的处理是非常普遍的,经常是需要将用户选择的图片上传到服务器,但是现在手机的分辨率越来越好了,随便一张照片都是2M或以上,如果直接显示到ImageView中,是会出现OOM的,上传到如服务器也会占用大量的流量,用户体验肯定不好了!
下面自己实现了图片的显示以及压缩功能,主要代码是从Volley的ImageRequest中copy过来,作为工具类方便以后图片处理
package com.img.util; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStream; import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Bitmap.CompressFormat; import android.net.Uri; import android.os.Environment; import android.provider.MediaStore.Images; import android.util.Log; /** * 图片压缩工具类 * * @author Administrator * */ public class ImageCompress { public static final String CONTENT = "content"; public static final String FILE = "file"; /** * 图片压缩参数 * * @author Administrator * */ public static class CompressOptions { public static final int DEFAULT_WIDTH = 400; public static final int DEFAULT_HEIGHT = 800; public int maxWidth = DEFAULT_WIDTH; public int maxHeight = DEFAULT_HEIGHT; /** * 压缩后图片保存的文件 */ public File destFile; /** * 图片压缩格式,默认为jpg格式 */ public CompressFormat imgFormat = CompressFormat.JPEG; /** * 图片压缩比例 默认为30 */ public int quality = 30; public Uri uri; } public Bitmap compressFromUri(Context context, CompressOptions compressOptions) { // uri指向的文件路径 String filePath = getFilePath(context, compressOptions.uri); if (null == filePath) { return null; } BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; Bitmap temp = BitmapFactory.decodeFile(filePath, options); int actualWidth = options.outWidth; int actualHeight = options.outHeight; int desiredWidth = getResizedDimension(compressOptions.maxWidth, compressOptions.maxHeight, actualWidth, actualHeight); int desiredHeight = getResizedDimension(compressOptions.maxHeight, compressOptions.maxWidth, actualHeight, actualWidth); options.inJustDecodeBounds = false; options.inSampleSize = findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight); Bitmap bitmap = null; Bitmap destBitmap = BitmapFactory.decodeFile(filePath, options); // If necessary, scale down to the maximal acceptable size. if (destBitmap.getWidth() > desiredWidth || destBitmap.getHeight() > desiredHeight) { bitmap = Bitmap.createScaledBitmap(destBitmap, desiredWidth, desiredHeight, true); destBitmap.recycle(); } else { bitmap = destBitmap; } // compress file if need if (null != compressOptions.destFile) { compressFile(compressOptions, bitmap); } return bitmap; } /** * compress file from bitmap with compressOptions * * @param compressOptions * @param bitmap */ private void compressFile(CompressOptions compressOptions, Bitmap bitmap) { OutputStream stream = null; try { stream = new FileOutputStream(compressOptions.destFile); } catch (FileNotFoundException e) { Log.e("ImageCompress", e.getMessage()); } bitmap.compress(compressOptions.imgFormat, compressOptions.quality, stream); } private static int findBestSampleSize(int actualWidth, int actualHeight, int desiredWidth, int desiredHeight) { double wr = (double) actualWidth / desiredWidth; double hr = (double) actualHeight / desiredHeight; double ratio = Math.min(wr, hr); float n = 1.0f; while ((n * 2) <= ratio) { n *= 2; } return (int) n; } private static int getResizedDimension(int maxPrimary, int maxSecondary, int actualPrimary, int actualSecondary) { // If no dominant value at all, just return the actual. if (maxPrimary == 0 && maxSecondary == 0) { return actualPrimary; } // If primary is unspecified, scale primary to match secondary's scaling // ratio. if (maxPrimary == 0) { double ratio = (double) maxSecondary / (double) actualSecondary; return (int) (actualPrimary * ratio); } if (maxSecondary == 0) { return maxPrimary; } double ratio = (double) actualSecondary / (double) actualPrimary; int resized = maxPrimary; if (resized * ratio > maxSecondary) { resized = (int) (maxSecondary / ratio); } return resized; } /** * 获取文件的路径 * * @param scheme * @return */ private String getFilePath(Context context, Uri uri) { String filePath = null; if (CONTENT.equalsIgnoreCase(uri.getScheme())) { Cursor cursor = context.getContentResolver().query(uri, new String[] { Images.Media.DATA }, null, null, null); if (null == cursor) { return null; } try { if (cursor.moveToNext()) { filePath = cursor.getString(cursor .getColumnIndex(Images.Media.DATA)); } } finally { cursor.close(); } } // 从文件中选择 if (FILE.equalsIgnoreCase(uri.getScheme())) { filePath = uri.getPath(); } return filePath; } }使用方式:
<span style="white-space:pre"> </span>ImageCompress compress = new ImageCompress(); ImageCompress.CompressOptions options = new ImageCompress.CompressOptions(); options.uri = imgUri; options.maxWidth=getWindowManager().getDefaultDisplay().getWidth(); options.maxHeight=getWindowManager().getDefaultDisplay().getHeight(); Bitmap bitmap = compress.compressFromUri(this, options);
默认压缩比例为30%,可以根据实际情况修改。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。