android图片导入防止OOM
来源:互联网 发布:mac键盘按键 编辑:程序博客网 时间:2024/04/29 23:11
类似帖子太多,当然我的也不是我写的,只是这代码比较典型,而且逻辑清晰,可以直接使用。
还是要经常学习别人写的比较优秀的代码,学习别人控制代码的逻辑,控制变量,内存,流程等,如果控制好的话代码就比较稳定。如下:
import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.BitmapFactory;import android.graphics.BitmapFactory.Options;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;/** * Class containing static utility methods for bitmap decoding and scaling * */public class ScalingUtilities { /** * Utility function for decoding an image resource. The decoded bitmap will * be optimized for further scaling to the requested destination dimensions * and scaling logic. * * @param res The resources object containing the image data * @param resId The resource id of the image data * @param dstWidth Width of destination area * @param dstHeight Height of destination area * @param scalingLogic Logic to use to avoid image stretching * @return Decoded bitmap */ public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight, ScalingLogic scalingLogic) { Options options = new Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); options.inJustDecodeBounds = false; options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth, dstHeight, scalingLogic); Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options); return unscaledBitmap; } /** * Utility function for creating a scaled version of an existing bitmap * * @param unscaledBitmap Bitmap to scale * @param dstWidth Wanted width of destination bitmap * @param dstHeight Wanted height of destination bitmap * @param scalingLogic Logic to use to avoid image stretching * @return New scaled bitmap object */ public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight, ScalingLogic scalingLogic) { Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(), dstWidth, dstHeight, scalingLogic); Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(), dstWidth, dstHeight, scalingLogic); Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(), Config.ARGB_8888); Canvas canvas = new Canvas(scaledBitmap); canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG)); return scaledBitmap; } /** * ScalingLogic defines how scaling should be carried out if source and * destination image has different aspect ratio. * * CROP: Scales the image the minimum amount while making sure that at least * one of the two dimensions fit inside the requested destination area. * Parts of the source image will be cropped to realize this. * * FIT: Scales the image the minimum amount while making sure both * dimensions fit inside the requested destination area. The resulting * destination dimensions might be adjusted to a smaller size than * requested. */ public static enum ScalingLogic { CROP, FIT } /** * Calculate optimal down-sampling factor given the dimensions of a source * image, the dimensions of a destination area and a scaling logic. * * @param srcWidth Width of source image * @param srcHeight Height of source image * @param dstWidth Width of destination area * @param dstHeight Height of destination area * @param scalingLogic Logic to use to avoid image stretching * @return Optimal down scaling sample size for decoding */ public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight, ScalingLogic scalingLogic) { if (scalingLogic == ScalingLogic.FIT) { final float srcAspect = (float)srcWidth / (float)srcHeight; final float dstAspect = (float)dstWidth / (float)dstHeight; if (srcAspect > dstAspect) { return srcWidth / dstWidth; } else { return srcHeight / dstHeight; } } else { final float srcAspect = (float)srcWidth / (float)srcHeight; final float dstAspect = (float)dstWidth / (float)dstHeight; if (srcAspect > dstAspect) { return srcHeight / dstHeight; } else { return srcWidth / dstWidth; } } } /** * Calculates source rectangle for scaling bitmap * * @param srcWidth Width of source image * @param srcHeight Height of source image * @param dstWidth Width of destination area * @param dstHeight Height of destination area * @param scalingLogic Logic to use to avoid image stretching * @return Optimal source rectangle */ public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight, ScalingLogic scalingLogic) { if (scalingLogic == ScalingLogic.CROP) { final float srcAspect = (float)srcWidth / (float)srcHeight; final float dstAspect = (float)dstWidth / (float)dstHeight; if (srcAspect > dstAspect) { final int srcRectWidth = (int)(srcHeight * dstAspect); final int srcRectLeft = (srcWidth - srcRectWidth) / 2; return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight); } else { final int srcRectHeight = (int)(srcWidth / dstAspect); final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2; return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight); } } else { return new Rect(0, 0, srcWidth, srcHeight); } } /** * Calculates destination rectangle for scaling bitmap * * @param srcWidth Width of source image * @param srcHeight Height of source image * @param dstWidth Width of destination area * @param dstHeight Height of destination area * @param scalingLogic Logic to use to avoid image stretching * @return Optimal destination rectangle */ public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight, ScalingLogic scalingLogic) { if (scalingLogic == ScalingLogic.FIT) { final float srcAspect = (float)srcWidth / (float)srcHeight; final float dstAspect = (float)dstWidth / (float)dstHeight; if (srcAspect > dstAspect) { return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect)); } else { return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight); } } else { return new Rect(0, 0, dstWidth, dstHeight); } }}
ScalingUtilities 主要用来编码图片资源成bitmap ,计算图片尺寸并缩放图片到指定尺寸
具体使用如下,可以有两种使用方式:
/** * Invoked when pressing button for showing result of the "Fit" decoding * method */ protected void fitButtonPressed() { final long startTime = SystemClock.uptimeMillis(); // Part 1: Decode image Bitmap unscaledBitmap = ScalingUtilities.decodeResource(getResources(), mSourceId, mDstWidth, mDstHeight, ScalingLogic.FIT); // Part 2: Scale image Bitmap scaledBitmap = ScalingUtilities.createScaledBitmap(unscaledBitmap, mDstWidth, mDstHeight, ScalingLogic.FIT); unscaledBitmap.recycle(); // Calculate memory usage and performance statistics final int memUsageKb = (unscaledBitmap.getRowBytes() * unscaledBitmap.getHeight()) / 1024; final long stopTime = SystemClock.uptimeMillis(); // Publish results mResultView.setText("Time taken: " + (stopTime - startTime) + " ms. Memory used for scaling: " + memUsageKb + " kb."); mImageView.setImageBitmap(scaledBitmap); } /** * Invoked when pressing button for showing result of the "Crop" decoding * method */ protected void cropButtonPressed() { final long startTime = SystemClock.uptimeMillis(); // Part 1: Decode image Bitmap unscaledBitmap = ScalingUtilities.decodeResource(getResources(), mSourceId, mDstWidth, mDstHeight, ScalingLogic.CROP); // Part 2: Scale image Bitmap scaledBitmap = ScalingUtilities.createScaledBitmap(unscaledBitmap, mDstWidth, mDstHeight, ScalingLogic.CROP); unscaledBitmap.recycle(); // Calculate memory usage and performance statistics final int memUsageKb = (unscaledBitmap.getRowBytes() * unscaledBitmap.getHeight()) / 1024; final long stopTime = SystemClock.uptimeMillis(); // Publish results mResultView.setText("Time taken: " + (stopTime - startTime) + " ms. Memory used for scaling: " + memUsageKb + " kb."); mImageView.setImageBitmap(scaledBitmap); }
这样先计算图片尺寸然后加载的方式可以防止一定程度的OOM,至于如此情形下图片过多过大防止OOM可以考虑在应用内存不足的时候计算剩余内存量,如果过少则停止加载图片资源到内存。
本例代码可以下载使用,已经上传,链接如下:
http://download.csdn.net/detail/bawang_cn/5033276
该文可以参见地址:
http://developer.sonymobile.com/2011/06/27/how-to-scale-images-for-your-android-application/
- android图片导入防止OOM
- android 加载图片防止oom的处理
- android中图片内存管理-防止OOM
- LruCache 防止图片OOM
- android图片加载防止OOM LruCache和DiskLruCache使用
- Android HttpConnection获取图片太大 处理办法 防止OOM
- 高效展示图片,防止OOM
- Android 水平加载图片 自定义 HorizontalScrollView,防止一次性加载出现性能问题,防止OOM
- android 压缩图片大小,防止OOM
- android加载大图,防止oom
- android 压缩图片大小,防止OOM
- Android 之 Bitmap 防止OOM
- 图片分辨率减少方法,防止OOM
- 防止图片decode时候(内存溢出)oom
- 图片缩小(防止OOM的方法)
- 内存中加载图片防止oom措施
- 高效加载图片防止OOM--总结
- 图片处理Lrucache 缓存防止OOM
- 又见回文
- php资源----Gscripts.net
- 正确使用memcached
- 【一题三解】POJ2299 Ultra-QuickSort (归并排序法)
- poj-3126-Prime Path-bfs
- android图片导入防止OOM
- 声乐唱法分类
- 字符编码笔记:ASCII,Unicode和UTF-8
- WIFI WPS 种类
- svn自启动命令
- fopen中r,w,a,+的含义
- Struts2上传
- Java 和c 的互调
- DataGrid行随鼠标移动变色及单击双击行事件处理