Android.graphics.Bitmap类里有一个内部类Bitmap.Config类,在Bitmap类里createBitmap(intwidth, int height, Bitmap.Config config)方法里会用到,打开个这个类一看
枚举变量
public static final Bitmap.Config ALPHA_8
public static final Bitmap.Config ARGB_4444
public static final Bitmap.Config ARGB_8888
public static final Bitmap.Config RGB_565
说白了就ALPHA_8就是Alpha由8位组成
ARGB_4444就是由4个4位组成即16位,
ARGB_8888就是由4个8位组成即32位,
RGB_565就是R为5位,G为6位,B为5位共16位
由此可见:
ALPHA_8 代表8位Alpha位图
ARGB_4444 代表16位ARGB位图
ARGB_8888 代表32位ARGB位图
RGB_565 代表8位RGB位图
位图位数越高代表其可以存储的颜色信息越多,当然图像也就越逼真。
图片的分辨率是3776 * 2520,每一点又是由ARGB色组成,每个色素占4个Byte,所以这张图片加载到内存中需要消耗的内存为:
3776 * 2520 * 4byte = 38062080byte,会造成内存溢出,那么如何加载大图片呢?
如何加载大分辨率图片
有时候我们确实会需要加载一些大分辨率的图片,但是对于移动设备而言,哪怕加载能成功那么大的内存也是一种浪费(屏幕分辨率限制),所以就需要想办法把图片按照一定比率压缩,使分辨率降低,以至于又不需要耗费很大的堆内存空间,又可以最大的利用设备屏幕的分辨率来显示图片。这里就用到一个BitmapFactory.Options对象,下面来介绍它。
BitmapFactory.Options为BitmapFactory的一个内部类,它主要用于设定与存储BitmapFactory加载图片的一些信息。下面是Options中需要用到的属性:
inJustDecodeBounds:如果设置为true,将不把图片的像素数组加载到内存中,仅加载一些额外的数据到Options中。
outHeight:图片的高度。
outWidth:图片的宽度。
inSampleSize:如果设置,图片将依据此采样率进行加载,不能设置为小于1的数。例如设置为4,分辨率宽和高将为原来的1/4,这个时候整体所占内存将是原来的1/16。
示例代码:
1 import android.os.Bundle;
2 import android.os.Environment;
3 import android.app.Activity;
4 import android.graphics.Bitmap;
5 import android.graphics.BitmapFactory;
6 import android.graphics.BitmapFactory.Options;
7 import android.view.Menu;
8 import android.view.View;
9 import android.view.WindowManager;
10 import android.widget.Button;
11 import android.widget.ImageView;
12 public class MainActivity extends Activity {
13
private Button btn_loadimage;
14
private ImageView iv_bigimage;
15
@Override
16
protected void onCreate(Bundle savedInstanceState) {
17
super.onCreate(savedInstanceState);
18
setContentView(R.layout.activity_main);
19
btn_loadimage = (Button) findViewById(R.id.btn_loadimage);
20
iv_bigimage = (ImageView) findViewById(R.id.iv_bigimage);
21
btn_loadimage.setOnClickListener(new View.OnClickListener() {
22
@Override
23
public void onClick(View v) {
24
// Bitmap bitmap=BitmapFactory.decodeFile("/sdcard/a.jpg");
25
// iv_bigimage.setImageBitmap(bitmap);
26
BitmapFactory.Options opts = new Options();
27
// 不读取像素数组到内存中,仅读取图片的信息
28
opts.inJustDecodeBounds = true;
29
BitmapFactory.decodeFile("/sdcard/a.jpg", opts);
30
// 从Options中获取图片的分辨率
31
int imageHeight = opts.outHeight;
32
int imageWidth = opts.outWidth;
33
// 获取Android屏幕的服务
34
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
35
// 获取屏幕的分辨率,getHeight()、getWidth已经被废弃掉了
36
// 应该使用getSize(),但是这里为了向下兼容所以依然使用它们
37
int windowHeight = wm.getDefaultDisplay().getHeight();
38
int windowWidth = wm.getDefaultDisplay().getWidth();
39
// 计算采样率
40
int scaleX = imageWidth / windowWidth;
41
int scaleY = imageHeight / windowHeight;
42
int scale = 1;
43
// 采样率依照最大的方向为准
44
if (scaleX > scaleY && scaleY >= 1) {
45
scale = scaleX;
46
}
47
if (scaleX < scaleY && scaleX >= 1) {
48
scale = scaleY;
49
}
50
// false表示读取图片像素数组到内存中,依照设定的采样率
51
opts.inJustDecodeBounds = false;
52
// 采样率
53
opts.inSampleSize = scale;
54
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/a.jpg", opts);
55
iv_bigimage.setImageBitmap(bitmap);
56
}
57
});
58
}
59 }
60
1 import android.os.Bundle;
2 import android.os.Environment;
3 import android.app.Activity;
4 import android.graphics.Bitmap;
5 import android.graphics.BitmapFactory;
6 import android.graphics.BitmapFactory.Options;
7 import android.view.Menu;
8 import android.view.View;
9 import android.view.WindowManager;
10 import android.widget.Button;
11 import android.widget.ImageView;
12 public class MainActivity extends Activity {
13
private Button btn_loadimage;
14
private ImageView iv_bigimage;
15
@Override
16
protected void onCreate(Bundle savedInstanceState) {
17
super.onCreate(savedInstanceState);
18
setContentView(R.layout.activity_main);
19
btn_loadimage = (Button) findViewById(R.id.btn_loadimage);
20
iv_bigimage = (ImageView) findViewById(R.id.iv_bigimage);
21
btn_loadimage.setOnClickListener(new View.OnClickListener() {
22
@Override
23
public void onClick(View v) {
24
// Bitmap bitmap=BitmapFactory.decodeFile("/sdcard/a.jpg");
25
// iv_bigimage.setImageBitmap(bitmap);
26
BitmapFactory.Options opts = new Options();
27
// 不读取像素数组到内存中,仅读取图片的信息
28
opts.inJustDecodeBounds = true;
29
BitmapFactory.decodeFile("/sdcard/a.jpg", opts);
30
// 从Options中获取图片的分辨率
31
int imageHeight = opts.outHeight;
32
int imageWidth = opts.outWidth;
33
// 获取Android屏幕的服务
34
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
35
// 获取屏幕的分辨率,getHeight()、getWidth已经被废弃掉了
36
// 应该使用getSize(),但是这里为了向下兼容所以依然使用它们
37
int windowHeight = wm.getDefaultDisplay().getHeight();
38
int windowWidth = wm.getDefaultDisplay().getWidth();
39
// 计算采样率
40
int scaleX = imageWidth / windowWidth;
41
int scaleY = imageHeight / windowHeight;
42
int scale = 1;
43
// 采样率依照最大的方向为准
44
if (scaleX > scaleY && scaleY >= 1) {
45
scale = scaleX;
46
}
47
if (scaleX < scaleY && scaleX >= 1) {
48
scale = scaleY;
49
}
50
// false表示读取图片像素数组到内存中,依照设定的采样率
51
opts.inJustDecodeBounds = false;
52
// 采样率
53
opts.inSampleSize = scale;
54
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/a.jpg", opts);
55
iv_bigimage.setImageBitmap(bitmap);
56
}
57
});
58
}
59 }
60
加载缩略图
1. 使用inJustDecodeBounds,读bitmap的长和宽。
2. 根据bitmap的长款和目标缩略图的长和宽,计算出inSampleSize的大小。
3. 使用inSampleSize,载入一个大一点的缩略图A
4. 使用createScaseBitmap,将缩略图A,生成我们需要的缩略图B。
5. 回收缩略图A。
需要注意的事情
createScaseBitmap如果原图和目标缩略图大小一致,那么不会生成一个新的bitmap直接返回bitmap,因此,回收的时候,要判断缩略图A是否就是缩略图B,如果说是的话,不要回收。
1 /**
2
* http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
3
*/
4 public class BitmapUtils {
5
private static int calculateInSampleSize(BitmapFactory.Options options,
6
int reqWidth, int reqHeight) {
7
final int height = options.outHeight;
8
final int width = options.outWidth;
9
int inSampleSize = 1;
10
if (height > reqHeight || width > reqWidth) {
11
final int halfHeight = height / 2;
12
final int halfWidth = width / 2;
13
while ((halfHeight / inSampleSize) > reqHeight
14
&& (halfWidth / inSampleSize) > reqWidth) {
15
inSampleSize *= 2;
16
}
17
}
18
return inSampleSize;
19
}
20
21
// 如果是放大图片,filter决定是否平滑,如果是缩小图片,filter无影响
22
private static Bitmap createScaleBitmap(Bitmap src, int dstWidth,
23
int dstHeight) {
24
Bitmap dst = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false);
25
if (src != dst) { // 如果没有缩放,那么不回收
26
src.recycle(); // 释放Bitmap的native像素数组
27
}
28
return dst;
29
}
30
31
// 从Resources中加载图片
32
public static Bitmap decodeSampledBitmapFromResource(Resources res,
33
int resId, int reqWidth, int reqHeight) {
34
final BitmapFactory.Options options = new BitmapFactory.Options();
35
options.inJustDecodeBounds = true;
36
BitmapFactory.decodeResource(res, resId, options); // 读取图片长款
37
options.inSampleSize = calculateInSampleSize(options, reqWidth,
38
reqHeight); // 计算inSampleSize
39
options.inJustDecodeBounds = false;
40
Bitmap src = BitmapFactory.decodeResource(res, resId, options); // 载入一个稍大的缩略图
41
return createScaleBitmap(src, reqWidth, reqHeight); // 进一步得到目标大小的缩略图
42
}
43
44
// 从sd卡上加载图片
45
public static Bitmap decodeSampledBitmapFromFd(String pathName,
46
int reqWidth, int reqHeight) {
47
final BitmapFactory.Options options = new BitmapFactory.Options();
48
options.inJustDecodeBounds = true;
49
BitmapFactory.decodeFile(pathName, options);
50
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
51
options.inJustDecodeBounds = false;
52
Bitmap src = BitmapFactory.decodeFile(pathName, options);
53
return createScaleBitmap(src, reqWidth, reqHeight);
54
}
55 }
1 /**
2
* http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
3
*/
4 public class BitmapUtils {
5
private static int calculateInSampleSize(BitmapFactory.Options options,
6
int reqWidth, int reqHeight) {
7
final int height = options.outHeight;
8
final int width = options.outWidth;
9
int inSampleSize = 1;
10
if (height > reqHeight || width > reqWidth) {
11
final int halfHeight = height / 2;
12
final int halfWidth = width / 2;
13
while ((halfHeight / inSampleSize) > reqHeight
14
&& (halfWidth / inSampleSize) > reqWidth) {
15
inSampleSize *= 2;
16
}
17
}
18
return inSampleSize;
19
}
20
21
// 如果是放大图片,filter决定是否平滑,如果是缩小图片,filter无影响
22
private static Bitmap createScaleBitmap(Bitmap src, int dstWidth,
23
int dstHeight) {
24
Bitmap dst = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false);
25
if (src != dst) { // 如果没有缩放,那么不回收
26
src.recycle(); // 释放Bitmap的native像素数组
27
}
28
return dst;
29
}
30
31
// 从Resources中加载图片
32
public static Bitmap decodeSampledBitmapFromResource(Resources res,
33
int resId, int reqWidth, int reqHeight) {
34
final BitmapFactory.Options options = new BitmapFactory.Options();
35
options.inJustDecodeBounds = true;
36
BitmapFactory.decodeResource(res, resId, options); // 读取图片长款
37
options.inSampleSize = calculateInSampleSize(options, reqWidth,
38
reqHeight); // 计算inSampleSize
39
options.inJustDecodeBounds = false;
40
Bitmap src = BitmapFactory.decodeResource(res, resId, options); // 载入一个稍大的缩略图
41
return createScaleBitmap(src, reqWidth, reqHeight); // 进一步得到目标大小的缩略图
42
}
43
44
// 从sd卡上加载图片
45
public static Bitmap decodeSampledBitmapFromFd(String pathName,
46
int reqWidth, int reqHeight) {
47
final BitmapFactory.Options options = new BitmapFactory.Options();
48
options.inJustDecodeBounds = true;
49
BitmapFactory.decodeFile(pathName, options);
50
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
51
options.inJustDecodeBounds = false;
52
Bitmap src = BitmapFactory.decodeFile(pathName, options);
53
return createScaleBitmap(src, reqWidth, reqHeight);
54
}
55 }
最后
以上就是拉长铃铛最近收集整理的关于图片在内存中的大小的全部内容,更多相关图片在内存中内容请搜索靠谱客的其他文章。

发表评论 取消回复