android bitmap.createbitmap内存溢出,android bitmap oom 优化

android使用位图显示图片,也就是像素点,jpg之类的压缩格式在android都会转成bitmap。

现在手机的分辨率也越来越高,480*800 大小的图片使用的内存大小:

480*800*32/8=1536000 =1.5M

32表示32位色,每个字节8位。

手机上有很多长图大小都是600*10000*32/8=24M,这样一来手机OOM是迟早的事。一些采用缩放和降低画质是解决不了问题的

例如下面这两种缩放还是会出现内存溢出的问题,

如何能让anroid获取网络图片时内存不OOM方法,使用BitmapFactory.decodeStream替代createBitmap方法,

原因是该方法直读取图片字节,调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap。

android使用Matrix实现bitmap缩放

[java]

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);

int width = bitmap.getWidth();

int height = bitmap.getHeight();

int newWidth = 640;

int newHeight = 480;

float scaleWidth = ((float) newWidth) / width;

float scaleHeight = ((float) newHeight) / height;

Matrix matrix = new Matrix();

matrix.postScale(scaleWidth, scaleHeight);

// create the new Bitmap object

Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);

[/java]

android使用options.inJustDecodeBounds实现bitmap缩放

[java]

BitmapFactory.Options options = new BitmapFactory.Options();

options.inJustDecodeBounds = true;

BitmapFactory.decodeFile(path, options);

if (options.mCancel || options.outWidth == -1

|| options.outHeight == -1) {

Log.d("OomDemo", "alert!!!" + String.valueOf(options.mCancel)

+ " " + options.outWidth + options.outHeight);

return null;

}

options.inSampleSize = Util.computeSampleSize(options, 600, (int) (1 * 1024 * 1024));

Log.d("OomDemo", "inSampleSize: " + options.inSampleSize);

options.inJustDecodeBounds = false;

options.inDither = false;

options.inPreferredConfig = Bitmap.Config.ARGB_8888; // 默认是Bitmap.Config.ARGB_8888

Bitmap bitmap = BitmapFactory.decodeFile(path, options);

[/java]

//四种构造Bitmap的使用的字节数

Bitmap.createBitmap(width, height,Bitmap.Config.ALPHA_8); 8bit

Bitmap.createBitmap(width, height,Bitmap.Config.ARGB_4444); 12bit

Bitmap.createBitmap(width, height,Bitmap.Config.ARGB_8888); 32bit

Bitmap.createBitmap(width, height,Bitmap.Config.RGB_565); 16bit

[java]

public class Util {

/*

* Compute the sample size as a function of minSideLength

* and maxNumOfPixels.

* minSideLength is used to specify that minimal width or height of a

* bitmap.

* maxNumOfPixels is used to specify the maximal size in pixels that is

* tolerable in terms of memory usage.

*

* The function returns a sample size based on the constraints.

* Both size and minSideLength can be passed in as IImage.UNCONSTRAINED,

* which indicates no care of the corresponding constraint.

* The functions prefers returning a sample size that

* generates a smaller bitmap, unless minSideLength = IImage.UNCONSTRAINED.

*

* Also, the function rounds up the sample size to a power of 2 or multiple

* of 8 because BitmapFactory only honors sample size this way.

* For example, BitmapFactory downsamples an image by 2 even though the

* request is 3. So we round up the sample size to avoid OOM.

*/

public static int computeSampleSize(BitmapFactory.Options options,

int minSideLength, int maxNumOfPixels) {

int initialSize = computeInitialSampleSize(options, minSideLength,

maxNumOfPixels);

int roundedSize;

if (initialSize <= 8) {

roundedSize = 1;

while (roundedSize < initialSize) {

roundedSize <<= 1;

}

} else {

roundedSize = (initialSize + 7) / 8 * 8;

}

return roundedSize;

}

public static int computeInitialSampleSize(BitmapFactory.Options options,

int minSideLength, int maxNumOfPixels) {

double w = options.outWidth;

double h = options.outHeight;

int lowerBound = (maxNumOfPixels == -1) ? 1 :

(int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));

int upperBound = (minSideLength == -1) ? 128 :

(int) Math.min(Math.floor(w / minSideLength),

Math.floor(h / minSideLength));

if (upperBound < lowerBound) {

// return the larger one when there is no overlapping zone.

return lowerBound;

}

if ((maxNumOfPixels == -1) &&

(minSideLength == -1)) {

return 1;

} else if (minSideLength == -1) {

return lowerBound;

} else {

return upperBound;

}

}

}

[/java]

android上屏幕密度和像素转换

[java]

//转换dip为px

public static int convertDIP2PX(Context context, int dip) {

float scale = context.getResources().getDisplayMetrics().density;

return (int)(dip*scale + 0.5f*(dip>=0?1:-1));

}

//转换px为dip

public static int convertPX2DIP(Context context, int px) {

float scale = context.getResources().getDisplayMetrics().density;

return (int)(px/scale + 0.5f*(px>=0?1:-1));

}

[/java]

可以参考这里的实现方法

http://www.java2s.com/Open-Source/Android/android-platform-apps/Gallery3D/com/cooliris/media/UriTexture.java.htm

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值