Android Bitmap二次采样,大图处理 经典 Android Bitmap二次采样,大图处理


Android Bitmap二次采样,大图处理

Bitmap 二次采样:
二次采样的目的是将高分辨率的图片进行采样缩放(个人理解,二次采样,应该是指二次调用了编码图片。但是两次编码所做的事情都是不一样的)。由于手机给每个APP分配的空间是有限的。所以若是不对图片进行缩放的话,就容易造成内存溢出(即OOM,out of memory)。
*官方文档推荐使用Glide来加载图片。
1.第一次采样:
第一次是获取图片的边框的长度与高度,BitmapFactory编码图片的方法有很多:

decodeByteArray(), decodeFile(), decodeResource()等。
  • 1
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //从英文就可理解,是否只是编码边框
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
/*得出图片的真实高度和宽度的时候,我们需要将其与我们需要的高度和宽度进行一个比值,从而得出我们需要的缩放的比例*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这里先解释下这个参数,文档中解释的大致意思是,若inSampleSize==4,那么原图的缩放就是1/4,像素比是1/16。并且若是inSampleSize<=1,都将设置为1。而且inSampleSize必须是2的幂次方,否则都会将inSampleSize舍入到最接近2的幂次方的数值。
inSampleSize

/** 该方法即是计算图片缩放比例
  * options 原图的参数
  */
public 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 inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) >= reqHeight
                && (halfWidth / inSampleSize) >= reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

2.第二次采样:
第二次采样就是按照计算出来的压缩比率来进行图片的编码。

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    options.inJustDecodeBounds = false;
    // 配置好计算的到的inSampleSize,将inJustDecodeBounds设置为false,那么即是将图片进行编码以的到我们需要的压缩的图片
    return BitmapFactory.decodeResource(res, resId, options);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Bitmap的像素格式:
ALPHA_8 只有一个alpha通道
ARGB_4444 这个从API 13开始不建议使用,因为质量太差
ARGB_8888 ARGB四个通道,每个通道8bit
RGB_565 每个像素占2Byte,其中红色占5bit,绿色占6bit,蓝色占5bit

参考文档:
https://developer.android.com/topic/performance/graphics/load-bitmap.html#load-bitmap
https://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize
https://developer.android.com/reference/android/graphics/Bitmap.Config.html
bitmap 内存管理,尚未学习与了解
https://developer.android.com/topic/performance/graphics/manage-memory.html
http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=498


Bitmap 二次采样:
二次采样的目的是将高分辨率的图片进行采样缩放(个人理解,二次采样,应该是指二次调用了编码图片。但是两次编码所做的事情都是不一样的)。由于手机给每个APP分配的空间是有限的。所以若是不对图片进行缩放的话,就容易造成内存溢出(即OOM,out of memory)。
*官方文档推荐使用Glide来加载图片。
1.第一次采样:
第一次是获取图片的边框的长度与高度,BitmapFactory编码图片的方法有很多:

decodeByteArray(), decodeFile(), decodeResource()等。
  • 1
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //从英文就可理解,是否只是编码边框
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
/*得出图片的真实高度和宽度的时候,我们需要将其与我们需要的高度和宽度进行一个比值,从而得出我们需要的缩放的比例*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这里先解释下这个参数,文档中解释的大致意思是,若inSampleSize==4,那么原图的缩放就是1/4,像素比是1/16。并且若是inSampleSize<=1,都将设置为1。而且inSampleSize必须是2的幂次方,否则都会将inSampleSize舍入到最接近2的幂次方的数值。
inSampleSize

/** 该方法即是计算图片缩放比例
  * options 原图的参数
  */
public 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 inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) >= reqHeight
                && (halfWidth / inSampleSize) >= reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

2.第二次采样:
第二次采样就是按照计算出来的压缩比率来进行图片的编码。

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    options.inJustDecodeBounds = false;
    // 配置好计算的到的inSampleSize,将inJustDecodeBounds设置为false,那么即是将图片进行编码以的到我们需要的压缩的图片
    return BitmapFactory.decodeResource(res, resId, options);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Bitmap的像素格式:
ALPHA_8 只有一个alpha通道
ARGB_4444 这个从API 13开始不建议使用,因为质量太差
ARGB_8888 ARGB四个通道,每个通道8bit
RGB_565 每个像素占2Byte,其中红色占5bit,绿色占6bit,蓝色占5bit

参考文档:
https://developer.android.com/topic/performance/graphics/load-bitmap.html#load-bitmap
https://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize
https://developer.android.com/reference/android/graphics/Bitmap.Config.html
bitmap 内存管理,尚未学习与了解
https://developer.android.com/topic/performance/graphics/manage-memory.html
http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=498

猜你喜欢

转载自blog.csdn.net/daimengs/article/details/80948290