传输文件,或者设置头像,我们一般都会检查原始图片的大小,作缩放处理。
常用的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;
}
常用的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 file
String fileName = "/sdcard/test.jpg";
FileUtil.writeToFile(fileName, photoData);
//save photo check sum to db
DataCenter.GetInstance().ModifyIMMUser();
//refresh ImageView
}
catch (FileNotFoundException exp)
{
exp.printStackTrace();
}
如果图片非常大,在执行BitmapFactory.decodeStream的时候就会抛出OOM异常。
我们来看看系统应用MMS是如何处理的,SMS添加了多媒体附件后就作MMS处理了,当附加文件原图超过300K,也会做个缩放处理,具体参考:com.android.mms.ui/.UriImage:
package com.android.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)
{
// Ignore
Log.e(TAG, "IOException caught while opening stream", e);
}
finally
{
if (null != input) {
try {
input.close();
} catch (IOException e) {
// Ignore
Log.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 file
String 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();
}
分享到:
相关推荐
安卓下显示图片经常遇到OOM问题,这里给出了常用解决方案
android图片墙,解决oom 博客地址: http://blog.csdn.net/pangzaifei/article/details/37763753
Android解决图片加载OOM与listview图片错位乱跳问题解决,开源的代码,里面有示例demo
解决Android加载图片出现的OOM问题
ViewPager加载大量图片oom解决方案
Android 图片下载以及内存处理防止OOM内存溢出 源码
基本上解决了OOM问题 如果 方便可以直接引用BitmapManager类到 项目中使用 解决blog 地址http://www.cnblogs.com/liongname/articles/2345087.html
有效控制了Android大图片、多图片加载的OOM异常。
本例主要介绍导入从src导入图片资源到应用,防止OOM,对图片做放大缩小等,可以学习代码的写法,下载可以直接运行使用
图像缩放限制---图像最小能缩放到圆形截取框范围 图像四方移动限制---图像移动边缘不会进入圆形截取范围内 图像无限放大---修改CutPicView的最大放大倍数参数即可 不行请联系QQ:2978549783(夜之瞳)资讯
如何为你的Android应用缩放图片,详细比较了android图片显示缩放前后用时,占用内存资源大小。防止加载大图是发生内存溢出
android Gallery 3d 图片浏览 倒影 oom解决了 读取可获取内置外置sd卡中图片
事件驱动解析是把文件转换成xml,然后一边读取一边解析,这样就对内存的占用就会很少,可以很好的处理poi出现OOM的问题。 maven添加需要的jar包 <groupId>org.apache.poi <artifactId>poi <version>3.15 ...
android 图片下载 防止OOM
android gridview 加载大量图片。无OOM。 程序运行默认加载SD卡内所有图片文件,这是我写了之后用在一款成熟app里面的。可用
挑战11张8k分辨率大图,共603MB大小连续进行压缩不OOM 博客介绍地址:http://blog.csdn.net/junjun071308/article/details/48606673
在Android平台上面,应用程序OOM异常永远都是值得关注的问题。通常这一块也是程序这中的重点之一。这下我就如何解决OOM作一点简单的介绍。 首先,OOM就是内存溢出,即Out Of Memory。也就是说内存占有量超过了VM所...
android加载大图避免oom,博客http://blog.csdn.net/u012305710/article/details/51079676
android解决OOM
WAS OOM异常宕机原因分析,websphere生成转存储文件