1.Bitmap类
Bitmap图像处理的最重要类之一。用它可以获取图像文件信息,进行图像颜色变换、剪切、旋转、缩放等操作,并可以指定格式保存图像文件
1.1Bitmap常用的方法
1.2Bitmap的颜色配置信息与压缩方式信息
Bitmap中有两个内部枚举类:Config和CompressFormat,
Config是用来设置颜色配置信息的,
CompressFormat是用来设置压缩方式的。
Config解析:
-
Bitmap.Config.ALPHA_8:颜色信息只由透明度组成,占8位。
-
Bitmap.Config.ARGB_4444:颜色信息由透明度与R(Red),G(Green),B(Blue)四部分组成,每个部分都占4位,总共占16位。
-
Bitmap.Config.ARGB_8888:颜色信息由透明度与R(Red),G(Green),B(Blue)四部分组成,每个部分都占8位,总共占32位。是Bitmap默认的颜色配置信息,也是最占空间的一种配置。
-
Bitmap.Config.RGB_565:颜色信息由R(Red),G(Green),B(Blue)三部分组成,R占5位,G占6位,B占5位,总共占16位。
通常我们优化Bitmap时,当需要做性能优化或者防止OOM(Out Of Memory),我们通常会使用Bitmap.Config.RGB_565这个配置,因为Bitmap.Config.ALPHA_8只有透明度,显示一般图片没有意义,Bitmap.Config.ARGB_4444显示图片不清楚,Bitmap.Config.ARGB_8888占用内存最多。
CompressFormat解析:
-
Bitmap.CompressFormat.JPEG:表示以JPEG压缩算法进行图像压缩,压缩后的格式可以是".jpg"或者".jpeg",是一种有损压缩。
-
Bitmap.CompressFormat.PNG:表示以PNG压缩算法进行图像压缩,压缩后的格式可以是".png",是一种无损压缩。
-
Bitmap.CompressFormat.WEBP:表示以WebP压缩算法进行图像压缩,压缩后的格式可以是".webp",是一种有损压缩,质量相同的情况下,WebP格式图像的体积要比JPEG格式图像小40%。美中不足的是,WebP格式图像的编码时间“比JPEG格式图像长8倍”。
1.3Bitmap对图像进行操作
1)Bitmap裁剪图像
itmap.createBitmap(Bitmap source, int x, int y, int width, int height)
根据源Bitmap对象source,创建出source对象裁剪后的图像的Bitmap。x,y分别代表裁剪时,x轴和y轴的第一个像素,width,height分别表示裁剪后的图像的宽度和高度。 注意:x+width要小于等于source的宽度,y+height要小于等于source的高度。
Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height,Matrix m, boolean filter)
这个方法只比上面的方法多了m和filter这两个参数,m是一个Matrix(矩阵)对象,可以进行缩放,旋转,移动等动作,filter为true时表示source会被过滤,仅仅当m操作不仅包含移动操作,还包含别的操作时才适用。其实上面的方法本质上就是调用这个方法而已。
public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height) {
return createBitmap(source, x, y, width, height, null, false);
}
2 )Bitmap缩放,旋转,移动图像
Bitmap缩放,旋转,移动,倾斜图像其实就是通过Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height,Matrix m, boolean filter)
方法实现的,只是在实现这些功能的同时还可以实现图像的裁剪。
// 定义矩阵对象
Matrix matrix = new Matrix();
// 缩放图像
matrix.postScale(0.8f, 0.9f);
// 向左旋转(逆时针旋转)45度,参数为正则向右旋转(顺时针旋转)
matrix.postRotate(-45);
//移动图像
//matrix.postTranslate(100,80);
Bitmap bitmap = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
matrix, true);
Matrix的postScale和postRotate方法还有多带两个参数的重载方法postScale(float sx, float sy, float px, float py)和postRotate(float degrees, float px, float py),后两个参数px和py都表示以该点为中心进行操作。
注意:虽然Matrix还可以调用postSkew方法进行倾斜操作,但是却不可以在此时创建Bitmap时使用。
3) Bitmap保存图像与释放资源
bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.feng);
File file=new File(getFilesDir(),"lavor.jpg");
if(file.exists()){
file.delete();
}
try {
FileOutputStream outputStream=new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG,90,outputStream);
outputStream.flush();
outputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
bitmap.recycle();//释放bitmap的资源,这是一个不可逆转的操作
3)Matrix拓展类
方法 | 介绍 |
---|---|
setRotate(float degrees, float px, float py) | 对图片进行旋转 |
setScale(float sx, float sy) | 对图片进行缩放 |
setTranslate(float dx, float dy) | 对图片进行平移 |
postTranslate(centerX, centerY) | 在上一次修改的基础上进行再次修改 set 每次操作都是最新的 会覆盖上次的操作 |
//显示原图
ImageView iv_src = (ImageView) findViewById(R.id.iv_src);
//显示副本
ImageView iv_copy = (ImageView) findViewById(R.id.iv_copy);
//[1]先把tomcat.png 图片转换成bitmap 显示到iv_src
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.tomcat);
//[1.1]操作图片
// srcBitmap.setPixel(20, 30, Color.RED);
iv_src.setImageBitmap(srcBitmap);
//[2]创建原图的副本
//[2.1]创建一个模板 相当于 创建了一个大小和原图一样的 空白的白纸
Bitmap copybiBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
//[2.2]想作画需要一个画笔
Paint paint = new Paint();
//[2.3]创建一个画布 把白纸铺到画布上
Canvas canvas = new Canvas(copybiBitmap);
//[2.4]开始作画
Matrix matrix = new Matrix();
//[2.5]对图片进行旋转
//matrix.setRotate(20, srcBitmap.getWidth()/2, srcBitmap.getHeight()/2);
//[2.5]对图片进行
// matrix.setScale(0.5f, 0.5f);
//[2.6]对图片进行平移
// matrix.setTranslate(30, 0);
//[2.7]镜面效果 如果2个方法一起用
// matrix.setScale(-1.0f, 1);
//post是在上一次修改的基础上进行再次修改 set 每次操作都是最新的 会覆盖上次的操作
// matrix.postTranslate(srcBitmap.getWidth(), 0);
//[2,7]倒影效果
matrix.setScale(1.0f, -1);
//post是在上一次修改的基础上进行再次修改 set 每次操作都是最新的 会覆盖上次的操作
matrix.postTranslate(0, srcBitmap.getHeight());
canvas.drawBitmap(srcBitmap,matrix , paint);
//[3]把copybimap显示到iv_copy上
iv_copy.setImageBitmap(copybiBitmap);
2.BitmapFactory类
创建位图对象从不同的来源,包括文件、流, 和字节数组。
2.1BitmapFactory常用方法
方法 | 说明 |
---|---|
decodeFile(String pathName, Options opts) | 从文件读取图片 |
decodeFile(String pathName) | 从文件读取图片 |
decodeFileDescriptor(FileDescriptor fd) | 从文件读取文件 与decodeFile不同的是这个直接调用JNI函数进行读取 效率比较高 |
decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) | 同上 |
decodeStream(InputStream is) | 从输入流读取图片 |
decodeStream(InputStream is, Rect outPadding, Options opts) | 从输入流读取图片 |
decodeStream(InputStream is, Rect outPadding, Options opts) | 从资源文件读取图片 |
decodeResource(Resources res, int id) | 从资源文件读取图片 |
decodeResource(Resources res, int id, Options opts) | 从资源文件读取图片 |
decodeByteArray(byte[] data, int offset, int length) | 从数组读取图片 |
decodeByteArray(byte[] data, int offset, int length, Options opts) | 从数组读取图片 |
BitmapFactory.decodeResource 加载的图片可能会经过缩放,该缩放目前是放在 java 层做的,效率比较低,而且需要消耗 java 层的内存。因此,如果大量使用该接口加载图片,容易导致OOM错误
BitmapFactory.decodeStream 不会对所加载的图片进行缩放,相比之下占用内存少,效率更高。
这两个接口各有用处,如果对性能要求较高,则应该使用 decodeStream;如果对性能要求不高,且需要 Android 自带的图片自适应缩放功能,则可以使用 decodeResource。
2.2BitmapFactory三种加载图片
- 1)从资源文件读取图片
Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.after19);
iv.setImageBitmap(bitmap);
- 2)从输入流中读取图片
FileInputStream fis=new FileInputStream(new File(getFilesDir()+"/psb.jpg"));
Bitmap bitmap= BitmapFactory.decodeStream(fis);
iv.setImageBitmap(bitmap);
- 3)从数组中读取图片
public static Bitmap readBitmapFromByteArray(byte[] data, int width, int height) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(data, 0, data.length, options);
float srcWidth = options.outWidth;
float srcHeight = options.outHeight;
int inSampleSize = 1;
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;
return BitmapFactory.decodeByteArray(data, 0, data.length, options);
}
2.3BitmapFactory常用操作
- 1)保存本地图片
public static void writeBitmapToFile(String filePath, Bitmap b, int quality) {
try {
File desFile = new File(filePath);
FileOutputStream fos = new FileOutputStream(desFile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
b.compress(Bitmap.CompressFormat.JPEG, quality, bos);
bos.flush();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
- 2)图片缩放
public static Bitmap bitmapScale(Bitmap bitmap, float scale) {
Matrix matrix = new Matrix();
matrix.postScale(scale, scale); // 长和宽放大缩小的比例
Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
return resizeBmp;
}
- 3)对 bitmap 进行裁剪
public Bitmap bitmapClip(Context context , int id , int x , int y){
Bitmap map = BitmapFactory.decodeResource(context.getResources(), id);
map = Bitmap.createBitmap(map, x, y, 120, 120);
return map;
}
3.BitmapFactory.option常用方法
Option参数类方法 | 说明 |
---|---|
public boolean inJustDecodeBounds | 如果设置为true,不获取图片,不分配内存,但会返回图片的高度宽度信息 |
public int inSampleSize | 图片缩放的倍数 |
public int outWidth | 获取图片的宽度值 |
public int outHeight | 获取图片的高度值 |
public int inDensity | 用于位图的像素压缩比 |
public int inTargetDensity | 用于目标位图的像素压缩比(要生成的位图) |
public byte[] inTempStorage | 创建临时文件,将图片存储 |
public boolean inScaled | 设置为true时进行图片压缩,从inDensity到inTargetDensity |
public boolean inDither | 如果为true,解码器尝试抖动解码 |
public Bitmap.Config inPreferredConfig | 设置解码器这个值是设置色彩模式,默认值是ARGB_8888,在这个模式下,一个像素点占用4bytes空间,一般对透明度不做要求的话,一般采用RGB_565模式,这个模式下一个像素点占用2bytes |
public String outMimeType | 设置解码图像 |
public boolean inPurgeable | 当存储Pixel的内存空间在系统内存不足时是否可以被回收 |
public boolean inInputShareable | inPurgeable为true情况下才生效,是否可以共享一个InputStream |
public boolean inPreferQualityOverSpeed | 为true则优先保证Bitmap质量其次是解码速度 |
public boolean inMutable | 配置Bitmap是否可以更改,比如:在Bitmap上隔几个像素加一条线段 |
public int inScreenDensity | 当前屏幕的像素密度 |