Android 图片缩放引起的OOM异常全篇
来源:互联网 发布:淘宝店铺怎么做 编辑:程序博客网 时间:2024/04/28 03:17
传输文件,或者设置头像,我们一般都会检查原始图片的大小,作缩放处理。
常用的Android版缩放图片代码:
如果图片非常大,在执行BitmapFactory.decodeStream的时候就会抛出OOM异常。
我们来看看系统应用MMS是如何处理的,SMS添加了多媒体附件后就作MMS处理了,当附加文件原图超过300K,也会做个缩放处理。
可以看出,MMS应用的方法是:先设置缩放选项,再读取缩放的图片数据到内存,规避了内存引起的OOM。
修改后的代码:
常用的Java版缩放图片代码:
public Bitmap getZoomImage(Bitmap src, int desW, int desH){Bitmap desImg = null;int srcW = src.getWidth(); // 原始图像宽int srcH = src.getHeight(); // 原始图像高int[] srcBuf = new int[srcW * srcH]; // 原始图片像素信息缓存src.getPixels(srcBuf, 0, srcW, 0, 0, srcW, srcH);// 计算插值表int[] tabY = new int[desH];int[] tabX = new int[desW];int sb = 0;int db = 0;int tems = 0;int temd = 0;int distance = srcH > desH ? srcH : desH;for (int i = 0; i <= distance; i++){/* 垂直方向 */tabY[db] = sb;tems += srcH;temd += desH;if (tems > distance){tems -= distance;sb++;}if (temd > distance){temd -= distance;db++;}}sb = 0;db = 0;tems = 0;temd = 0;distance = srcW > desW ? srcW : desW;for (int i = 0; i <= distance; i++){/* 水平方向 */tabX[db] = (short) sb;tems += srcW;temd += desW;if (tems > distance){tems -= distance;sb++;}if (temd > distance){temd -= distance;db++;}}// 生成放大缩小后图形像素int[] desBuf = new int[desW * desH];int dx = 0;int dy = 0;int sy = 0;int oldy = -1;for (int i = 0; i < desH; i++){if (oldy == tabY[i]){System.arraycopy(desBuf, dy - desW, desBuf, dy, desW);}else{dx = 0;for (int j = 0; j < desW; j++){desBuf[dy + dx] = srcBuf[sy + tabX[j]];dx++;}sy += (tabY[i] - oldy) * srcW;}oldy = tabY[i];dy += desW;}// 生成图片desImg = Bitmap.createBitmap(desBuf, desW, desH, Bitmap.Config.ARGB_8888);return desImg;}public Bitmap getZoomImage(Bitmap src, int desW, int desH){Bitmap desImg = null;int srcW = src.getWidth(); // 原始图像宽int srcH = src.getHeight(); // 原始图像高int[] srcBuf = new int[srcW * srcH]; // 原始图片像素信息缓存src.getPixels(srcBuf, 0, srcW, 0, 0, srcW, srcH);// 计算插值表int[] tabY = new int[desH];int[] tabX = new int[desW];int sb = 0;int db = 0;int tems = 0;int temd = 0;int distance = srcH > desH ? srcH : desH;for (int i = 0; i <= distance; i++){/* 垂直方向 */tabY[db] = sb;tems += srcH;temd += desH;if (tems > distance){tems -= distance;sb++;}if (temd > distance){temd -= distance;db++;}}sb = 0;db = 0;tems = 0;temd = 0;distance = srcW > desW ? srcW : desW;for (int i = 0; i <= distance; i++){/* 水平方向 */tabX[db] = (short) sb;tems += srcW;temd += desW;if (tems > distance){tems -= distance;sb++;}
常用的Android版缩放图片代码:
ContentResolver cr = this.getContentResolver();try{InputStream in = cr.openInputStream(uri);Bitmap bitmap = BitmapFactory.decodeStream(in);try{in.close();}catch (IOException e){e.printStackTrace();}if(null == bitmap){Toast.makeText(this, “Head is not set successful,Decode bitmap failure”, 2000);}//原始图片的尺寸int bmpWidth = bitmap.getWidth();int bmpHeight = bitmap.getHeight();//缩放图片的尺寸float scaleWidth = (float) 40 / bmpWidth;float scaleHeight = (float) 40 / bmpHeight;Matrix matrix = new Matrix();matrix.postScale(scaleWidth, scaleHeight);//产生缩放后的Bitmap对象Bitmap resizeBitmap = Bitmap.createBitmap(bitmap, 0, 0, bmpWidth, bmpHeight, matrix, false);bitmap.recycle();//Bitmap to byte[]byte[] photoData = Bitmap2Bytes(resizeBitmap);//save fileString fileName = “/sdcard/test.jpg”;FileUtil.writeToFile(fileName, photoData);//save photo check sum to dbDataCenter.GetInstance().ModifyIMMUser();//refresh ImageView}catch (FileNotFoundException exp){exp.printStackTrace();}
如果图片非常大,在执行BitmapFactory.decodeStream的时候就会抛出OOM异常。
我们来看看系统应用MMS是如何处理的,SMS添加了多媒体附件后就作MMS处理了,当附加文件原图超过300K,也会做个缩放处理。
package eoe.mms.ui;public class UriImage{private int mWidth;private int mHeight;… …//private void decodeBoundsInfo(){InputStream input = null;try{input = mContext.getContentResolver().openInputStream(mUri);BitmapFactory.Options opt = new BitmapFactory.Options();opt.inJustDecodeBounds = true;//只描边,不读取数据BitmapFactory.decodeStream(input, null, opt);mWidth = opt.outWidth;mHeight = opt.outHeight;}catch (FileNotFoundException e){// IgnoreLog.e(TAG, “IOException caught while opening stream”, e);}finally{if (null != input) {try {input.close();} catch (IOException e) {// IgnoreLog.e(TAG, “IOException caught while closing stream”, e);}}}}private byte[] getResizedImageData(int widthLimit, int heightLimit){int outWidth = mWidth;int outHeight = mHeight;int s = 1;while ((outWidth / s > widthLimit) || (outHeight / s > heightLimit)){s *= 2;}//先设置选项BitmapFactory.Options options = new BitmapFactory.Options();//returning a smaller image to save memory.options.inSampleSize = s;InputStream input = null;try{input = mContext.getContentResolver().openInputStream(mUri);Bitmap b = BitmapFactory.decodeStream(input, null, options);//注意看options的用法if (b == null) {return null;}ByteArrayOutputStream os = new ByteArrayOutputStream();b.compress(CompressFormat.JPEG, MessageUtils.IMAGE_COMPRESSION_QUALITY, os);return os.toByteArray();} catch (FileNotFoundException e) {Log.e(TAG, e.getMessage(), e);return null;} finally {if (input != null) {try {input.close();} catch (IOException e) {Log.e(TAG, e.getMessage(), e);}}}}… …}
可以看出,MMS应用的方法是:先设置缩放选项,再读取缩放的图片数据到内存,规避了内存引起的OOM。
修改后的代码:
ContentResolver cr = this.getContentResolver();try{InputStream in = cr.openInputStream(uri);BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeStream(in, null, options);try{in.close();}catch (IOException e){e.printStackTrace();}int mWidth = options.outWidth;int mHeight = options.outHeight;int sWidth = 40;int sHeight = 40;int s = 1;while ((mWidth / s > sWidth * 2) || (mHeight / s > sHeight * 2)){s *= 2;}options = new BitmapFactory.Options();options.inSampleSize = s;in = cr.openInputStream(uri);Bitmap bitmap = BitmapFactory.decodeStream(in, null, options);try{in.close();}catch (IOException e){e.printStackTrace();}if(null == bitmap){Toast.makeText(this, “Head is not set successful,Decode bitmap failure”, 2000);return ;}//原始图片的尺寸int bmpWidth = bitmap.getWidth();int bmpHeight = bitmap.getHeight();//缩放图片的尺寸float scaleWidth = (float) sWidth / bmpWidth;float scaleHeight = (float) sHeight / bmpHeight;Matrix matrix = new Matrix();matrix.postScale(scaleWidth, scaleHeight);//产生缩放后的Bitmap对象Bitmap resizeBitmap = Bitmap.createBitmap(bitmap, 0, 0, bmpWidth, bmpHeight, matrix, false);bitmap.recycle();Bitmap resizeBitmap = bitmap;//Bitmap to byte[]byte[] photoData = bitmap2Bytes(resizeBitmap);//save fileString fileName = “/sdcard/test.jpg”;FileUtil.writeToFile(fileName, photoData);private byte[] bitmap2Bytes(Bitmap bm){ByteArrayOutputStream baos = new ByteArrayOutputStream();bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);return baos.toByteArray();}
- Android 图片缩放引起的OOM异常全篇
- Android 图片缩放引起的OOM异常全篇
- Android: 缩放图片文件引起的OOM异常
- Android: 缩放图片文件引起的OOM异常
- Android: 缩放图片文件引起的OOM异常
- Android: 缩放图片文件引起的OOM异常
- 如何处理图片引起的OOM异常?
- Android加载图片引起的OOM解决方案(转)
- 解决android缩放图片导致OOM的一个方案
- android 加载图片oom异常
- 图片资源过大引起OOM的问题
- Android 加载打图片出现OOM异常的处理方式
- 图片缩放,解决oom
- 图片缩放,解决OOM
- Android的加载大图片引起内存问题之OOM异常
- 图片二次采样有效防止因图片引起的OOM
- 处理getdrawable的方法引起的OOM异常
- android图片的打开和缩放时出现oom处理过程
- WIN_静态库与动态库的加载、VC project参数设置
- 带遮罩的div弹出层demo(可多层)
- objective-c通过日历获取 年、月、周、日、时、分、秒
- vmware在XP上安装linux fc4详细说明
- Qt 将窗口显示在显示屏中央
- Android 图片缩放引起的OOM异常全篇
- 六种异常处理的陋习
- QT实现屏幕滑动效果窗体
- 数据库技巧——MySQL十大优化技巧
- IOS开发中的UIScreen、UIView、UIWindow和UIViewController
- Win7修改键盘布局
- ffmpeg Tutorial学习
- Ext.encode与Ext.decode的JSON转换
- MRTG生成首页报错解决方法