我们都知道一个App的成败,首先取决于是否具有优秀的UI,而除了交互功能之外还需要丰富的图片背景和动画去支撑。在开发中我们应用到的图片不仅仅包括.png、.gif、.9.png、.jpg和各种Drawable系对象,还包括位图Bitmap,而且图片的处理也经常是影响着一个程序的高效性和健壮性。

一、Bitmap概述

Bitmap代表一张位图,扩展名可以是.bmp或者.dib。位图是Windows标准格式图形文件,它将图像定义为由点(像素)组成,每个点可以由多种色彩表示,包括2、4、8、16、24和32位色彩。例如,一幅1024×768分辨率的32位真彩图片,其所占存储字节数为:1024×768×32/8=3072KB,虽然位图文件图像效果好,但是非压缩格式的,需要占用较大存储空间,不利于在网络上传送Android系统当中,Bitmap是图像处理最重要的中转类之一。用它可以获取图像文件信息,借助Matrix进行图像剪切、旋转、缩放等操作,再以指定格式保存图像文件。

二、构造Bitmap对象

通常我们构造一个类的对象,都是可以通过其对应的构造方法。然而Bitmap是采用了工厂的设计模式,所以一般不会直接调用构造方法。

1、通过Bitmap的静态方法static Bitmap createBitmap()系

方法名(只列出部分方法) 用法说明
createBitmap(Bitmap src) 复制位图
createBitmap(Bitmap src,int x ,int y,int w,int h) 从源位图src的指定坐标(x,y)开始,截取宽w,高h的部分,用于创建新的位图对象
createScaledBitmap(Bitmap src,int w ,int h,boolean filter) 对源位图src缩放成宽为w,高为h的新位图
createBitmap(int w ,int h,Bitmap.Config config) 创建一个宽w,高h的新位图(config为位图的内部配置枚举类)
createBitmap(Bitmap src,int x ,int y,int w,int h,Matrix m,boolean filter) 从源位图src的指定坐标(x,y)开始,截取宽w,高h的部分,按照Matrix变换创建新的位图对象

2、通过BitmapFactory工厂类的static Bitmap decodeXxx()系

方法名(只列出部分方法) 参数及解释
decodeByteArray(byte[] data, int offset, int length) 从指定字节数组的offset位置开始,将长度为length的数据解析成位图
decodeFile(String pathName) 从pathName对应的文件解析成的位图对象
decodeFileDescriptor(FileDescriptor fd) 从FileDescriptor中解析成的位图对象
decodeResource(Resource res,int id) 根据给定的资源Id解析成位图
decodeStream(InputStream in) 把输入流解析成位图

三、Bitmap相关类之Path、Matrix

1、Path类的应用

有使用PS经验的都知道”路径”这么一个概念,可以把几个点连成一条“路径”,Android里的Path也是如此。在实际应用中我们可以调用Canvas的drawPath方法即可绘制图形,为了实现丰富的绘制效果,Android还定义了一个PathEffect系列类(ComposePathEffect, CornerPathEffect, DashPathEffect, DiscretePathEffect, PathDashPathEffect, SumPathEffect

1.1、Path类的构造方法

Path();
Path(Path src);

1.2、Path类的一些常用方法

部分方法 用法说明
public void addArc (RectF oval, float startAngle, float sweepAngle) 绘制弧形路径
public void addCircle (float x, float y, float radius, Path.Direction dir) 绘制圆形路径
public void addOval (RectF oval, Path.Direction dir) 绘制椭圆路径
public void lineTo (float x, float y) 把(x,y)连接到一起成为一条折线
public void moveTo (float x, float y)  

1.3、Path的实际应用

绘制跟随路径显示的字符串

package com.crazymo.graphicsdemo;

public class MyPathView extends View {
final String STR_TITLE="跟随路径显示的字符串";
Path[] paths=new Path[3];
Paint paint;
public MyPathView(Context ctx){
super(ctx);
paths[0]=new Path();
paths[0].moveTo(0,0);
for(int i=1;i<7;i++){
//随机生成7个点的Y坐标并将他们炼成一条路径
paths[0].lineTo(i*30,(float)Math.random()*30);
}
paths[1]=new Path();
RectF rectF=new RectF(0,0,200,120);
paths[1].addOval(rectF,Path.Direction.CCW); paths[2]=new Path();
paths[2].addArc(rectF,60,180);
//初始化画笔
paint=new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.GREEN);
paint.setStrokeWidth(1);
} @Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
canvas.translate(40, 40);
//从右边开始绘制即右对齐
paint.setTextAlign(Paint.Align.RIGHT);
paint.setTextSize(20);
//绘制路径
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(paths[0], paint);
paint.setStyle(Paint.Style.FILL);
canvas.drawTextOnPath(STR_TITLE, paths[0], -8, 20, paint);//沿着路径绘制文字
//画布下移120
canvas.translate(0,60);
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(paths[1], paint);
paint.setStyle(Paint.Style.FILL);
canvas.drawTextOnPath(STR_TITLE, paths[1], -20,20,paint); canvas.translate(0,120);
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(paths[2], paint);
paint.setStyle(Paint.Style.FILL);
canvas.drawTextOnPath(STR_TITLE,paths[2],-10,20,paint);
}
}

2、使用Matrix控制图片和View的平移、旋转、缩放等。

2.1、构造Matrix对象

public Matrix();
public Matrix(Matrix src);

2.2、Matrix一些常用的方法

部分方法 用法说明
public void setTranslate(float dx, float dy) 绘制弧形路径
public void setSkew(float kx, float ky, float px, float py) 控制Matrix以(px,py)为轴心进行倾斜,kx,ky为X,Y方向上的倾斜距离
public void setSkew(float px, float py) kx,ky为X,Y方向上的倾斜距离
public void setRotate(float degree) 控制Matrix旋转degree度
public void setRotate(float degree,float px,float py) 控制Matrix以轴心(px,py)旋转degree度
setScale(float sx, float sy, float px, float py) 控制Matrix以(px,py)为轴心缩放,sx,sy为X,Y方向上的缩放距离
void setScale(float sx, float sy)  

2.3、Marix的简单应用

自定义一个使用Matrix的View

/**
* Created by cmo on 16-4-1.
*/
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.util.AttributeSet; public class CostomView extends View { private Bitmap mBitmap;
private Matrix matrix; public CostomView(Context context) {
super(context);
matrix = new Matrix();
} public CostomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
matrix = new Matrix();
} public CostomView(Context context, AttributeSet attrs) {
super(context, attrs);
matrix = new Matrix();
} public Bitmap getmBitmap() {
return mBitmap;
} public void setmBitmap(Bitmap mBitmap) {
this.mBitmap = mBitmap;
invalidate();
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mBitmap != null) {
canvas.drawBitmap(mBitmap, matrix, null);
}
} public void rotate(float degree) {
if (mBitmap != null) {
matrix.preRotate(degree, mBitmap.getWidth() / 2,
mBitmap.getHeight() / 2);
invalidate();
} }
//平移
public void translate(float dx, float dy) {
if (mBitmap != null) {
matrix.postTranslate(dx, dy);
invalidate();
}
}
//缩放
public void scale(float sx, float sy) {
if (mBitmap != null) {
matrix.postScale(sx, sy);
invalidate();
}
}
//镜像(相当于是照镜子里的自己)
public void mirror() {
if (mBitmap != null) {
matrix.postScale(-1, 1);
matrix.postTranslate(mBitmap.getWidth(), 0);
invalidate();
}
}
//倒影
public void shadow() {
if (mBitmap != null) {
matrix.postScale(1, -1);
matrix.postTranslate(0, mBitmap.getHeight());
invalidate();
}
}
public void skew(float kx, float ky){
if (mBitmap != null) {
matrix.postSkew(kx, ky);
invalidate();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.crazymo.matrixdemo.CostomView
android:id="@+id/costomview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_translate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="平移"/>
<Button
android:id="@+id/btn_scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="缩放"/>
<Button
android:id="@+id/btn_rotate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="旋转"/> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_skew"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="倾斜"/>
<Button
android:id="@+id/btn_mirro"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="镜像"/>
<Button
android:id="@+id/btn_shadow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="倒影"/>
</LinearLayout>
</LinearLayout>
package com.crazymo.matrixdemo;
/**
* Created by cmo on 16-4-1.
*/
public class CostViewActivity extends Activity {
private CostomView mCostomView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cotomview);
mCostomView = (CostomView) findViewById(R.id.costomview);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.mipmap.bcg);
mCostomView.setmBitmap(bitmap); ((Button) findViewById(R.id.btn_rotate))
.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
mCostomView.rotate(15);
}
});
((Button) findViewById(R.id.btn_scale))
.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
mCostomView.scale(1.8f, 1.8f);
}
});
((Button) findViewById(R.id.btn_translate))
.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
mCostomView.translate(100, 100);
}
});
((Button) findViewById(R.id.btn_skew))
.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
mCostomView.skew(-0.3f, 0.3f);
}
});
((Button) findViewById(R.id.btn_mirro))
.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
mCostomView.mirror();
}
});
((Button) findViewById(R.id.btn_shadow))
.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
mCostomView.shadow();
}
});
}
}

四、Bitmap的简单应用

1、从资源文件中获取Bitmap

Bitmap rawBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.bcg); 

2、从SD卡里获取Bitmap

String SDCarePath=Environment.getExternalStorageDirectory().toString();
String filePath=SDCarePath+"/"+"demo.jpg";
Bitmap rawBitmap1 = BitmapFactory.decodeFile(filePath, null);
InputStream inputStream=getBitmapInputStreamFromSDCard("demo.jpg");
Bitmap rawBitmap2 = BitmapFactory.decodeStream(inputStream);

3、设置图片的圆角,返回设置后的Bitmap

public Bitmap toRoundCorner(Bitmap bitmap, int pixels) {
Bitmap roundCornerBitmap = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(roundCornerBitmap);
int color = 0xff424242;// int color = 0xff424242;
Paint paint = new Paint();
paint.setColor(color);
// 防止锯齿
paint.setAntiAlias(true);
Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
RectF rectF = new RectF(rect);
float roundPx = pixels;
// 相当于清屏
canvas.drawARGB(0, 0, 0, 0);
// 先画了一个带圆角的矩形
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
// 再把原来的bitmap画到现在的bitmap!!!注意这个理解
canvas.drawBitmap(bitmap, rect, rect, paint);
return roundCornerBitmap;
}

4、将图片高宽和的大小kB压缩

//得到图片原始的高宽
int rawHeight = rawBitmap.getHeight();
int rawWidth = rawBitmap.getWidth();
// 设定图片新的高宽
int newHeight = 500;
int newWidth = 500;
// 计算缩放因子
float heightScale = ((float) newHeight) / rawHeight;
float widthScale = ((float) newWidth) / rawWidth;
// 新建立矩阵
Matrix matrix = new Matrix();
matrix.postScale(heightScale, widthScale);
// 设置图片的旋转角度
// matrix.postRotate(-30);
// 设置图片的倾斜
// matrix.postSkew(0.1f, 0.1f);
// 将图片大小压缩
// 压缩后图片的宽和高以及kB大小均会变化
Bitmap newBitmap = Bitmap.createBitmap(rawBitmap, 0, 0, rawWidth,rawWidth, matrix, true);

5、将Bitmap转换为Drawable Drawable转Bitmap

Drawable newBitmapDrawable = new BitmapDrawable(Bitmap);
//如果要获取BitMapDrawable中所包装的BitMap对象,可以用getBitMap()方法;
Bitmap bitmap = newBitmapDrawable.getBitmap();

Android入门——Bitmap和BitmapFactory的更多相关文章

  1. android图像与图像处理系列(一、Bitmap和BitmapFactory)

    1.Drawable对象 Android应用添加了Drawabe资源之后,Android SDK会为这份资源文件在R清单文件中创建一个索引项:R.drawable.file_name,接着我们可以在x ...

  2. Android学习之——图形图像处理(Bitmap、BitmapFactory)(一)

    转载自http://blog.csdn.net/csxwc/article/details/10345235 Bitmap是Android系统中的图像处理的最重要的类之一.用它可以获取图像文件信息,对 ...

  3. [Android学习笔记]Bitmap,BitmapDrawable,BitmapFactory学习笔记

    Bitmap:图片文件的封装,可以看做是一张位图此类中的静态方法可以通过源Bitmap创建新的Bitmap对象此类封装了位图的一些信息Bitmap文档 BitmapFactory:一个工具类,用于创建 ...

  4. Android 使用Bitmap将自身保存为文件,BitmapFactory从File中解析图片并防止OOM

    1.使用Bitmap将自身保存为文件 public boolean saveBitmapAsFile(String name, Bitmap bitmap) { File saveFile = new ...

  5. zxing学习笔记 android入门

    对于刚开始学习android开发的童鞋们来说,若有一个简单而又全面的android工程能来剖析,那就是再好不过了,zxing就是不错得例子.    zxing的源码可以到google code上下载, ...

  6. Android入门(十六)调用摄像头相册

    原文链接:http://www.orlion.ga/665/ 一.调用摄像头 创建一个项目ChoosePicDemo,修改activity_main.xml: <LinearLayout xml ...

  7. android 入门-android自定义控件

    第一种:继承View 实现自己的属性 <com.cc.imagewithmarkersample.MyView android:id="@+id/myviewid" andr ...

  8. Android处理Bitmap的一些方法

    http://www.it165.net/pro/html/201305/5795.html # 文件与Bitmap间的方法 1. 从文件载入Bitmap 01./** 02.* @brief 从文件 ...

  9. Android中Bitmap, Drawable, Byte,ID之间的转化

    Android中Bitmap, Drawable, Byte,ID之间的转化 1.  Bitmap 转化为 byte ByteArrayOutputStream out = new ByteArray ...

随机推荐

  1. Python day字符串所有使用

    字符串所有的操作name = "dio"names = "my\t name is {Name} and i am a {job}"print(name.cap ...

  2. PythonOOP面向对象编程1

    什么是对象? 对象是指现实中的物体或实体(拥有一系列变量.函数(方法)的) 什么事面向对象? 把一切看成对象(实例),让对象和对象之间建立关联关系 对象都有什么特征? 属性(名词)实例变量 姓名.年龄 ...

  3. Wget使用

    http://www.tuicool.com/articles/A7BRny wget / curl 是两个比较方便的测试http功能的命令行工具,大多数情况下,测试http功能主要是查看请求响应 头 ...

  4. UnrealEngine4针对游戏模式的思考

    游戏能够概括为三类:单进程联机(超级玛丽).小规模联机(魔兽争霸.CS),大规模联机(魔兽世界). watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmx1c ...

  5. heap-adb shell查看堆栈使用

    今天在使用eclipse中的heap查看oom的时候,发现手机(eng版本)非常的卡,后来换成usr版本,又连接不上eclipse.最后听别人说,可以使用adb shell进行查看.指令如下 adb ...

  6. 在Qt Creator的项目中添加头文件和库

    在Qt Creator中的工程中,工程通过.pro文件管理. 额外需要连接的连接库unix:LIBS += -L your_lib_path -lyour_libwin32:LIBS += your_ ...

  7. 15.Node.js REPL(交互式解释器)

    转自:http://www.runoob.com/nodejs/nodejs-tutorial.html Node.js REPL(Read Eval Print Loop:交互式解释器) 表示一个电 ...

  8. Linux下基于LDAP统一用户认证的研究

    Linux下基于LDAP统一用户认证的研究                   本文出自 "李晨光原创技术博客" 博客,谢绝转载!

  9. 用C#生成随机中文汉字验证码的基本原理

    前几天去申请免费QQ号码,突然发现申请表单中的验证码内容换成了中文,这叫真叫我大跌眼镜感到好笑,Moper上的猫儿们都大骂腾讯采用中文验证码.^_^  我不得不佩服腾讯为了防止目前网络上横行的QQ号码 ...

  10. java DSA Signature Sign And Verify

    SignatureSignAndVerify import java.security.KeyPair; import java.security.KeyPairGenerator; import j ...