Android - bitmap简单总结

Bitmap是Android中 处理 图片的一个重要的类。用它可以获取图片信息,进行图片剪切、平移、旋转、缩放等操作,并可以指定格式保存图片文件。
一、 Bitmap对象的获取
获取Bitmap主要依靠BitmapFactory类,其API注释为:Creates Bitmap objects from various sources, including files, streams, and byte-arrays.
即利用文件、数据流和字节数组等资源创建Bitmap对象,主要涉及到以下几个方法:
mBitmap = BitmapFactory.decodeFile("/storage/emulated/0/DCIM/Camera/20151130_221159_temp.jpg");

除了利用 BitmapFactory类的decodeXXX()方法外,还有一些获取bitmap对象的方法,比如:
android.content.res包下的Resources.java中,
public InputStream openRawResource(int id, TypedValue value)方法可用来间接获取Bitmap对象:
InputStream is = getResources().openRawResource(R.drawable.ic_launcher);
BitmapDrawable bd = new BitmapDrawable(is);
Bitmap bm = bd.getBitmap();
或者
BitmapDrawable bd = (BitmapDrawable) getResources().getDrawable(R.drawable.ic_launcher);
Bitmap bm = bd.getBitmap();

之上是Bitmap对象的获取。

二、BitmapFactory.Options
BitmapFactory类中,除了各种用于创建Bitmap对象的方法外,还有一个比较重要的东西,就是 BitmapFactory的静态内部类 Options。
其中,有几个较常用的属性:
1、inJustDecodeBounds: 设置inJustDecodeBounds为true后,调用decodeFile方法时,并不真正分配创建Bitmap所需的空间,适用于仅仅只需要获取一些属性——比如原始图片的长度和宽度等的情况,比如在压缩图片时,需要计算属性inSampleSize的值,就需要获取 原始图片的长度和宽度 。一般步骤如下:

先设置inJustDecodeBounds= true,调用decodeFile()得到图像的基本信息;利用图像的宽度(或者高度,或综合)以及目标宽度(高度),得到inSampleSize值,再设置inJustDecodeBounds= false,调用decodeFile()得到完整的图像数据。

2、 inSampleSize:缩放图片采用的比率值,设置之后, 将 以2的指数的倒数倍对原始图片进行 放。
3、inPreferredConfig:设置图片的色彩模式,可选值为 Android.graphics.Bitmap的一个内部类Bitmap.Config的枚举值: 常用 ALPHA_8、 RGB_565和 ARGB_8888,默认是 ARGB_8888, 其中,A代表透明度,R代表红色,G代表绿色,B代表蓝色
4、 inPurgeable:如果设置为true的话,表示 在内存空间不足的时候,允许 所创建的bitmap 被回收。
5 inInputShareable:当 inPurgeable被设置为false时,该参数失去意义,当 inPurgeable被设置为true时, inInputShareable 的意义还不太理解,API注释为: If inPurgeable is true, then this field determines whether the bitmap can share a reference to the input data (inputstream, array, etc.) or if it must make a deep copy.慢慢理解吧!
6、 outHeight、outWidth:图像的高度和宽度
7、 inScreenDensity: The pixel density of the actual screen that is being used. 
8、 inTargetDensity:The pixel density of the destination this bitmap will be drawn to. 

三、图片操作
下边是比较常用的利用bitmap对图片进行操作的例子:
1、对图像进行剪切,主要使用Bitmap的createBitmap方法,该方法有6种重载形式,类似:
public static Bitmap createBitmap(Bitmap source, int x, int y,  int width, int height) {}
source:代表源bitmap
x、y:代表需要进行剪切的起始坐标
width、height:代表需要截取的图片的宽度和高度
需要注意: x + width    must be <= bitmap.width()  并且   y + height must be <= bitmap.height()  (否则这就是错误提示)
2、对图像进行缩放, 对bitmap进行缩放,可以选择多种方式:
A、 使用Bitmap的 带有Matrix参数的 createBitmap方法
public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter) {}
例如:
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);//原图片
Matrix mtrix = new Matrix();
mtrix.postScale(0.25f, 0.25f);
Bitmap targetBitmap = srcBitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), mtrix, true);//目标图片
B、借助Canvas的scale方法
public void scale(float sx, float sy) {}
不过这是canvas类的方法,从效果上看,bitmap实现了缩放,但本质是canvas的缩放导致的
参数sx代表水平方向的缩放倍数,sy代表竖直方向上的缩放倍数
3、对图像进行旋转, 也可借助Matrix来实现, 例如:
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);//原图片
Matrix mtrix = new Matrix();
mtrix.postScale(0.25f, 0.25f);
mtrix.postRotate(90);//顺时针旋转90度
Bitmap targetBitmap = srcBitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), mtrix, true);//目标图片
4、 借助Matrix来实现 对图像的平移

从上边的内容中,我们可以发现, Matrix在对bitmap进行旋转、缩放等过程中起着重要的作用,事实上,在android中,常使用 Matrix这个类和Bitmap的 createBitmap方法搭配来完成图片的平移、缩放和旋转操作。关于Matrix的介绍,网上有非常好的文章可以参考,本文不再详写。
作为 createBitmap方法的参数,使用之前当然要为 Matrix对象赋值以指定需要对图片采取什么样的操作,从Matrix.java中,可以看出Matrix对图片进行操作主要还是依据成员变量 mValues的值,即,在调用 createBitmap方法之前,需要为 Matrix的成员变量 mValues赋值, 可选方式有两种:
第一、调用Matrix的set、pre、post方法, 如: setScale(float, float)、preTranslate(float, float)和postScale(float, float)等。需要注意的是, set、pre、post方法的执行顺序为 (该图片中的内容来源于网络,谢谢作者):
Android - bitmap简单总结 - H , W , G , T ... .. - H , W , G , T ... ..
  第二、使用Matrix类的setValues (float[] values) 方法, 如:
Matrix matrix = new Matrix();  
float[] values ={0.707f,-0.707f,0.0f,0.707f,0.707f,0.0f,0.0f,0.0f,1.0f};  
matrix.setValues(values);  
Bitmap dstbmp = Bitmap.createBitmap(bmp, 0, 0, 400, 500, matrix, true);  
canvas.drawBitmap(dstbmp, 0, 200, null);  

在Java代码中为imageview设置图片的方式有:
public void setImageResource(int resId) {}
public void setImageDrawable(Drawable drawable) {}
public void setImageBitmap(Bitmap bm) {
setImageDrawable(new BitmapDrawable(mContext.getResources(), bm));
}
比较明显,它们接收的参数类型不同,另外setImageBitmap方法中会先将bitmap对象转化成drawable对象,并最终调用setImageDrawable方法
每一次调用 setImageBitmap方法都会new一个BitmapDrawable对象,所以,API中也给出了提示:
// if this is used frequently, may handle bitmaps explicitly to reduce the intermediate drawable object
大致意思是,如果需要频繁调用 setImageBitmap方法,最好提供一个中间drawable对象。

bitmap的保存:
mBitmap2.compress(Bitmap.CompressFormat.JPEG, 80,输出流对象);
第一个参数:指定格式,第二个参数:压缩比率,第三个参数:输出流对象

bitmap的其他操作:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 读取本地资源的图片 */  
  2. public Bitmap readBitMap(int resId) {  
  3.     BitmapFactory.Options opt = new BitmapFactory.Options();  
  4.     opt.inPreferredConfig = Bitmap.Config.RGB_565;  
  5.     opt.inPurgeable = true;  
  6.     opt.inInputShareable = true;  
  7.     InputStream is = getResources().openRawResource(resId);  
  8.     return BitmapFactory.decodeStream(is, null, opt);  
  9. }  
  10. /** Drawable 转 Bitmap */  
  11. public static Bitmap drawableToBitmap(Drawable drawable) {    
  12.     Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),  
  13.             drawable.getIntrinsicHeight(),  
  14.             drawable.getOpacity() != PixelFormat.OPAQUE ?   
  15.                     Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);    
  16.                     Canvas canvas = new Canvas(bitmap);   
  17.     drawable.setBounds(00, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());    
  18.     drawable.draw(canvas);    
  19.     return bitmap;    
  20. }  


需要增加一个matrix运用的demo
还需要处理的问题:
1:bitmap和drawable相互转换之后图片大小不同的问题
2:bitmap的显示
3:bitmap的图片保存
4:bitmap的OOM问题
5:bitmap的读取等问题
6:imageview的 setImageDrawable和setImageBitmap的区别
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值