图形与图像处理

1)、BitMap

<1>、常用方法

public void recycle()——回收位图占用的内存空间,把位图标记为Dead 
public final boolean isRecycled() ——判断位图内存是否已释放 
public final int getWidth()——获取位图的宽度 
public final int getHeight()——获取位图的高度 
public final boolean isMutable()——图片是否可修改 
public int getScaledWidth(Canvas canvas)——获取指定密度转换后的图像的宽度 
public int getScaledHeight(Canvas canvas)——获取指定密度转换后的图像的高度 
public boolean compress(CompressFormat format, int quality, OutputStream stream)——按指定的图片格式以及画质,将图片转换为输出流。 
format:Bitmap.CompressFormat.PNG或Bitmap.CompressFormat.JPEG 
quality:画质,0-100.0表示最低画质压缩,100以最高画质压缩。对于PNG等无损格式的图片,会忽略此项设置。 
常用的静态方法: 
public static Bitmap createBitmap(Bitmap src) ——以src为原图生成不可变得新图像 
public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, 
            int dstHeight, boolean filter)——以src为原图,创建新的图像,指定新图像的高宽以及是否可变。 
public static Bitmap createBitmap(int width, int height, Config config)——创建指定格式、大小的位图 
public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height) source为原图,创建新的图片,指定起始坐标以及新图像的高宽。 
public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)


<2>、位图显示

1)、直接显示:imageView.setImageBitmap(Bitmap);

2)、转换为BitmapDrawable对象显示位图,如: imageView.setImageDrawable(bmpDrawable);

3)、Canvas类显示位图 canvas.drawBitmap(bitmap, 10, 10, null);   


<3>、位图缩放

1)、将一个位图按照需求重画一遍drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)。 
2)在原有位图的基础上,缩放原位图,创建一个新的位图:CreateBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter) 
3)借助Canvas的scale(float sx, float sy) ,不过要注意此时整个画布都缩放了。 
4)借助Matrix:(可实现位图的平移、旋转、倾斜等变换)   

Bitmap dstbmp=Bitmap.createBitmap(bmp,0,0,bmp.getWidth(), bmp.getHeight(),matrix,true);   


2)、BitmapDrawable

<1>、常用的构造函数
Resources res=getContext().getResources()//获取资源 
public BitmapDrawable(Resources res)——创建一个空的drawable。(Response用来指定初始时所用的像素密度)替代public BitmapDrawable()方法(此方法不处理像素密度) 
public BitmapDrawable(Resources res, Bitmap bitmap)——Create drawable from a bitmap 
public BitmapDrawable(Resources res, String filepath)——Create a drawable by opening a given file path and decoding the bitmap. 
public BitmapDrawable(Resources res, java.io.InputStream is)——Create a drawable by decoding a bitmap from the given input stream. 

或者: 
BitmapDrawable bmpDraw=(BitmapDrawable)res.getDrawable(R.drawable.pic180); 


<2>、BitmapDrawable bitmap:

Bitmap bmp=bmpDraw.getBitmap(); 


<3>、BitMap和BitmapDrawable的区别

1)、Bitmap继承Parcelable,是一个可以跨进程传输的对象,BitmapDrawable继承Drawable,Drawable只是一个抽象类,此类是一个存放数据流的载体。BitmapDrawable就是封装了一个位图
2)、使用情况:如果想绑定imageView之类的控件,两者都可以用,而想要将图片数据转换成其它对象,Bitmap功能更强大,而BitmapDrawable只是一个流的载体,所以一般获取src资源文件的时候用得多,而想要把资源图片截入到Bitmap需要转换后才可得到Bitmap对象。

3)

对比项

显示清晰度

占用内存

支持缩放

支持色相色差调整

支持旋转

支持透明色

绘制速度

支持像素操作

Bitmap

相同

Drawable

相同

 小

 

注意:Android支持三种格式的位图图像:.png (preferred),.jpg (acceptable), .gif (discouraged)。.png格式图片优先,.jpg格式也可以,但是效果没有.png好,.gif支持最差drawable目录中图像的二进制文件在构建程序时可以改变。如果你打算读一个图像作为字节流并将它转换成一个位图,把你的图片放在在res /raw/文件夹里,在那里他们不会被优化。


3)、BitmapFactory

<1>、常用静态方法

读取一个文件路径得到一个位图。如果指定文件为空或者不能解码成文件,或者opts参数只请求大小信息时即当Options.inJustDecodeBounds=true,只请求图片的大小信息 ,则返回NULL。

public static Bitmap decodeFile(String pathName, Options opts) 
public static Bitmap decodeFile(String pathName) 

根据指定的资源id创建bitmap对象
public static Bitmap decodeResource(Resources res, int id) 
public static Bitmap decodeResource(Resources res, int id, Options opts) 
从输入流中解码位图 
public static Bitmap decodeStream(InputStream is) 
从字节数组offset位置开始,将长度为length的字节数据解码生成不可变的位图 
public static Bitmap decodeByteArray(byte[] data, int offset, int length) 

 

<2>、BitmapFactory.Options

public boolean inJustDecodeBounds——如果设置为true,不获取图片,不分配内存,但会返回图片的高度宽度信息。 
public int inSampleSize——图片缩放的倍数。如果设为4,则宽和高都为原来的1/4,则图是原来的1/16。 
public int outWidth——获取图片的宽度值 
public int outHeight——获取图片的高度值 
public int inDensity——用于位图的像素压缩比 
public int inTargetDensity——用于目标位图的像素压缩比(要生成的位图) 
public boolean inScaled——设置为true时进行图片压缩,从inDensity到inTargetDensity。

Public inPurgeable; ——如果 inPurgeable 设为True的话表示使用BitmapFactory创建的Bitmap 用于存储Pixel的内存空间在系统内存不足时可以被回收, 在应用需要再次访问Bitmap的Pixel时(如绘制Bitmap或是调用getPixel), 系统会再次调用BitmapFactory decoder重新生成Bitmap的Pixel数组。  为了能够重新解码图像,bitmap要能够访问存储Bitmap的原始数据。 在inPurgeable为false时表示创建的Bitmap的Pixel内存空间不能被回收, 这样BitmapFactory在不停decodeByteArray创建新的Bitmap对象, 当isPurgable设为true时,系统中内存不足时, 可以回收部分Bitmap占据的内存空间,这时一般不会出现OutOfMemory 错误。 


4)、Matrix

Matrix是Android提供的一个矩阵工具类,用于将平移、旋转、缩放、倾斜等变换应用到指定图像或view组件上。 Matrix 由 9 个 float 值构成,是一个 3*3 的矩阵

<1>、Matrix的操作,总共分为translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种,每一种变换在Android的API里都提供了set(用于设置Matrix中的值每次set一次,整个Matrix的数组都会变掉, post(后乘,根据矩阵的原理,相当于左乘)pre(先乘,相当于矩阵中的右乘)三种操作方式,除了translate,其他三种操作都可以指定中心点如果不指定,默认情况下,是围绕(0,0)点来进行。

注意:后调用的pre操作先执行,而后调用的post操作则后执行,set方法一旦调用即会清空之前matrix中的所有变换,

例如:

1.matrix.preScale(0.5f, 1);

2.matrix.preTranslate(10, 0);

3.matrix.postScale(0.7f, 1);

4.matrix.postTranslate(15, 0);

等价于:

translate(10, 0) -> scale(0.5f, 1) -> scale(0.7f, 1) -> translate(15, 0)

1.matrix.preScale(0.5f, 1);

2.matrix.setScale(1, 0.6f);

3.matrix.postScale(0.7f, 1);

4.matrix.preTranslate(15, 0);

等价于

translate(15, 0) -> scale(1, 0.6f) -> scale(0.7f, 1)

matrix.preScale (0.5f, 1)将不起作用。


<2>、变换操作

1)Translate——x轴和y轴上简单地移动图像。setTranslate方法采用两个浮点数作为参数,表示在每个轴上移动的数量。第一个参数是图像将在x轴上移动的数量,而第二个参数是图像将在y轴上移动的数量。在x轴上使用正数将向右移动图像,而使用负数将向左移动图像。在y轴上使用正数将向下移动图像,而使用负数将向上移动图像。

2)、Scale ——setScale方法采用两个浮点数作为参数,第一个参数是x轴的缩放比例,而第二个参数是y轴的缩放比例。如:matrix.setScale(1.5f,1f);即宽为原来的1.5倍,高不变,matrix.setScale(0.5f,1f);即宽为原来的0.5倍,高不变;

3)、Rotate——它采用一个浮点数表示旋转的角度。围绕默认点(0,0),正数将顺时针旋转图像,而负数将逆时针旋转图像,其中默认点是图像的左上角

4)、Skew ——错切变换的效果就是让所有点的x坐标(或者y坐标)保持不变,而对应的y坐标(或者x坐标)则按比例发生平移,且平移的大小和该点到x(或y轴)的垂直距离成正比。错切变换,属于等面积变换,即一个形状在错切变换的前后,其面积是相等的。

5)、setScale和postTranslate,它们允许跨单个轴(或者两个轴)翻转图像。如果以一个负数缩放,那么会将该图像绘制到坐标系统的负值空间。

例如:





5)、关于图片OOM

<1>、尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source,decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间。

<2>、如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of Memory异常, 例如:

BitmapFactory.Options opt = new BitmapFactory.Options();  
     opt.inPreferredConfig = Bitmap.Config.RGB_565;   
   opt.inPurgeable = true;  
   opt.inInputShareable = true;  

ALPHA_8:每个像素占用1byte内存

ARGB_4444:每个像素占用2byte内存

ARGB_8888:每个像素占用4byte内存

RGB_565:每个像素占用2byte内存),

举个例子,如果一个图片的分辨率是1024*768,采用ARGB_8888,那么占用的空间就是1024*768*4=3MB,这张图片需要占用3M的内存空间

<3>、图片压缩

1)、自定义算法

首先我们可以通过设置一个Options的属性inJustDecodeBounds=true,然后使用BitmapFactory.decodeXXX方法,让options作为参数,这样,我们在不分配内存的情况下,可以通过options读取图片的大小,outWidth和outHeight。其次通过原始图片的大小和你需要图片的大小来计算出需要缩放的比例。最后通过缩放比例值作为options.inSampleSize的值,再次调用BitmapFactory.decodeXXX,在调用方法前一定要设置inJustDecodeBounds=faluse。

2)、用ThumbnailUtils类

Android 2.2开始系统新增了一个缩略图ThumbnailUtils类,位于framework包下的android.media.ThumbnailUtils位置,可以帮助我们从mediaprovider中获取系统中的视频或图片文件的缩略图,该类提供了三种静态方法可以直接调用获取。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值