关于Android 中 Options.inSampleSize怎么用
答案:1 悬赏:30 手机版
解决时间 2021-11-15 05:04
- 提问者网友:我一贱你就笑
- 2021-11-14 19:45
关于Android 中 Options.inSampleSize怎么用
最佳答案
- 五星知识达人网友:一把行者刀
- 2021-11-14 19:51
这个是读取bitmap时用到的属性,是为了对原图降采样.
比如原图是一个 4000 * 4000 点阵的图,占用内存就是 4000 * 4000 * 单个像素占用字节数
单个像素占用字节数取决于你用的是 RGB565, ARGB8888 等. 4000 * 4000 这个解析度已很接近目前市面主流机器的默认照片解析度.
假设你用的是RGB565解析这张图,那一个点就占用2个字节.如果完整解析这个图片,就需要 大约3.2MB的内存.
如果你用了一个GridView,同时显示了30张这种图,那几乎可以确定你会收到一个OOM异常.
所以需要对这种大图进行降采样,以减小内存占用.毕竟拇指大小的地方根本用不着显示那么高的解析度.
因为直接从点阵中隔行抽取最有效率,所以为了兼顾效率, inSampleSize 这个属性只认2的整数倍为有效.
比如你将 inSampleSize 赋值为2,那就是每隔2行采1行,每隔2列采一列,那你解析出的图片就是原图大小的1/4.
这个值也可以填写非2的倍数,非2的倍数会被四舍五入.
综上,用这个参数解析bitmap就是为了减少内存占用.
一下是我的一个根据指定大小对图片文件降采样读取的一个函数,供参考.
public static Bitmap decodeBitmapForSize(String path, int width, int height) {
final BitmapFactory.Options options = new BitmapFactory.Options();
if (width != 0 && height != 0) {
// decode with inJustDecodeBounds=true to check size
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// calculate inSampleSize according to the requested size
options.inSampleSize = calculateInSampleSize(options, width, height);
options.inJustDecodeBounds = false;
}
// decode bitmap with the calculated inSampleSize
options.inPreferredConfig = Config.RGB_565;
options.inPurgeable = true;
options.inInputShareable = true;
return BitmapFactory.decodeFile(path, options);
}
private static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int initSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
initSize = Math.round((float) height / (float) reqHeight);
} else {
initSize = Math.round((float) width / (float) reqWidth);
}
}
int roundedSize;
if (initSize <= 8) {
roundedSize = 1;
while (roundedSize < initSize) {
roundedSize <<= 1;
}
} else {
roundedSize = (initSize + 7) / 8 * 8;
}
return roundedSize;
}
比如原图是一个 4000 * 4000 点阵的图,占用内存就是 4000 * 4000 * 单个像素占用字节数
单个像素占用字节数取决于你用的是 RGB565, ARGB8888 等. 4000 * 4000 这个解析度已很接近目前市面主流机器的默认照片解析度.
假设你用的是RGB565解析这张图,那一个点就占用2个字节.如果完整解析这个图片,就需要 大约3.2MB的内存.
如果你用了一个GridView,同时显示了30张这种图,那几乎可以确定你会收到一个OOM异常.
所以需要对这种大图进行降采样,以减小内存占用.毕竟拇指大小的地方根本用不着显示那么高的解析度.
因为直接从点阵中隔行抽取最有效率,所以为了兼顾效率, inSampleSize 这个属性只认2的整数倍为有效.
比如你将 inSampleSize 赋值为2,那就是每隔2行采1行,每隔2列采一列,那你解析出的图片就是原图大小的1/4.
这个值也可以填写非2的倍数,非2的倍数会被四舍五入.
综上,用这个参数解析bitmap就是为了减少内存占用.
一下是我的一个根据指定大小对图片文件降采样读取的一个函数,供参考.
public static Bitmap decodeBitmapForSize(String path, int width, int height) {
final BitmapFactory.Options options = new BitmapFactory.Options();
if (width != 0 && height != 0) {
// decode with inJustDecodeBounds=true to check size
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// calculate inSampleSize according to the requested size
options.inSampleSize = calculateInSampleSize(options, width, height);
options.inJustDecodeBounds = false;
}
// decode bitmap with the calculated inSampleSize
options.inPreferredConfig = Config.RGB_565;
options.inPurgeable = true;
options.inInputShareable = true;
return BitmapFactory.decodeFile(path, options);
}
private static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int initSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
initSize = Math.round((float) height / (float) reqHeight);
} else {
initSize = Math.round((float) width / (float) reqWidth);
}
}
int roundedSize;
if (initSize <= 8) {
roundedSize = 1;
while (roundedSize < initSize) {
roundedSize <<= 1;
}
} else {
roundedSize = (initSize + 7) / 8 * 8;
}
return roundedSize;
}
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯