BitMap的基本使用
我们创建一个BItMap有几种方式?
答:两种:一种是使用BitmapFactory类去加载,另一种是使用Bitmap类加载。
一、BitmapFactory
1.1 BitmapFactory提供了多种创建bitmap的静态方法
1 2 3 4 5 6 7
|
public static Bitmap decodeResources(Resources res,int id)
public static Bitmap decodeResources(Resources res,int id,Options opt)
|
1 2 3 4 5
|
public static Bitmap decodeFile(String pathName); public static Bitmap decodeFile(String pathName,Options opt);
|
1 2 3 4 5 6
|
public static Bitmap decodeByteArray(byte[] data,int offset , int length); public static Bitmap decodeByteArray(byte[] data,int offset , int length,Options opt);
|
1 2 3 4 5
|
public static Bitmap decodeFileDescriptor(FileDescriptor fd); public static Bitmap decodeFileDescriptor(FileDescriptor fd,Rect outPadding,Options opt);
|
decodeFile、 decodeResource、decodeStream和decodeByteArray,分别用于支持从文件系统、资源、输入流以及字节数组中加载出一个Bitmap对象,其中decodeFile和decodeResource又间接调用了decodeStream方法,这四类方法最终是在Android的底层实现的,对应着BitmapFactory类的几个native 方法。
一个native方法就是一个Java调用非Java代码的接口。一个native方法是指该方法的实现由非Java语言实现,比如用C或C++实现。
1.2 Bitmap.Options
想要创建一个Bitmap
有很多种方法,其中很多方法都要求传入一个Bitmap.Options
,它是什么呢,有什么作用呢?
这个参数的作用非常大,他可以设置Bitmap的采样率,通过改变图片的宽度高度和缩放比例等,以达到减少图片像素数的目的,一言以蔽之,通过设置这个参数我们可以很好的控制显示和使用Bitmap
。实际开发过程中,可以灵活设置该值,以降低OOM
发生的概率。
- 如何高效地加载bitmap?
通过BitmapFactory.Options
按一定的采样率
来加载缩小后的图片,将缩小后的图片在ImageView
中显示,这样就会降低内存占用从而在一定程度上避免OOM,提高了Bitmap 加载时的性能。BitmapFactory提供的加载图片的四类方法都支持BitmapFactory.Options参数
- 通过BitmapFactory.Options 来缩放图片,主要用到了inSampleSize参数,即采样率。
当inSampleSize为1时,采样后的图片大小为图片的原始大小;
当inSampleSize大于1时,比如为2,那么采样后的图片其宽/高均为原图大小的1/2,而像素数为原图的1/4,其占有的内存大小也为原图的1/4。
拿一张1024×1024像素的图片来说,假定采用ARGB8888格式存储,那么它占有的内存为1024×1024×4即4MB,如果inSampleSize为2,那么采样后的图片其内存占用只有512×512×4,即1MB。
采样率同时作用于宽/高,这将导致缩放后的图片大小以采样率的2次方形式递减,即缩放比例为1/ (inSampleSize的2次方)
比如inSampleSize为4,那么缩放比例就是1/16。
有一种特殊情况,那就是当inSampleSize 小于1时,其作用相当于1,即无缩放效果。
参数说明:
举例说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(), R.drawable.img3, options); float srcWidth = options.outWidth; float srcHeight = options.outHeight; int inSampleSize = 1; float height = 100; float width = 528;
if (srcHeight > height || srcWidth > width) { if (srcWidth > srcHeight) { inSampleSize = Math.round(srcHeight / height); } else { inSampleSize = Math.round(srcWidth / width); } }
options.inJustDecodeBounds = false; options.inSampleSize = inSampleSize;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img3, options); float outWidth = options.outWidth; float outHeight = options.outHeight; binding.image.setImageBitmap(bitmap);
Log.d(TAG, "图片的内存: " + bitmap.getAllocationByteCount()); Log.d(TAG, "图片的采樣率: " + inSampleSize); Log.d(TAG, "原來图片的宽度/高度: " + srcWidth + " / " + srcHeight); Log.d(TAG, "現在图片的宽度/高度: " + outWidth + " / " + outHeight);
|
二. Bitmap静态方法
1 2 3 4 5 6 7 8 9 10
| static Bitmap createBitmap(int width , int height Bitmap.Config config)
static Bitmap createBitmap(Bitmap bm)
static Bitmap createBitmap(Bitmap bm,int x,int y,int width,int height)
static Bitmap createBitmap(Bitmap bm,int x,int y,int width,int height,Matrix m,boolean filter);
createScaledBitmap(Bitmap bm,int dstWidth,int dstHeight,boolean filter)
|
这些方法大致可以分为三类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public static Bitmap createBitmap(@NonNull Bitmap source, int x, int y, int width, int height, @Nullable Matrix m, boolean filter)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
public static Bitmap createBitmap(@NonNull DisplayMetrics display, @NonNull @ColorInt int[] colors, int offset, int stride, int width, int height, @NonNull Config config)
|
1 2 3 4 5
|
public static Bitmap createScaledBitmap(@NonNull Bitmap src, int dstWidth, int dstHeight,boolean filter)
|
三.创建Bitmap的总结
- 加载图像可以使用BitmapFactory和Bitmap.create系列方法
- 可以通过Options实现缩放图片,获取图片信息,配置缩放比例等功能
- 如果需要裁剪或者缩放图片,只能使用create系列函数
- 注意加载和创建bitmap事通过try catch捕捉OOM异常