Android入门——Bitmap和BitmapFactory
我们都知道一个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的更多相关文章
- android图像与图像处理系列(一、Bitmap和BitmapFactory)
1.Drawable对象 Android应用添加了Drawabe资源之后,Android SDK会为这份资源文件在R清单文件中创建一个索引项:R.drawable.file_name,接着我们可以在x ...
- Android学习之——图形图像处理(Bitmap、BitmapFactory)(一)
转载自http://blog.csdn.net/csxwc/article/details/10345235 Bitmap是Android系统中的图像处理的最重要的类之一.用它可以获取图像文件信息,对 ...
- [Android学习笔记]Bitmap,BitmapDrawable,BitmapFactory学习笔记
Bitmap:图片文件的封装,可以看做是一张位图此类中的静态方法可以通过源Bitmap创建新的Bitmap对象此类封装了位图的一些信息Bitmap文档 BitmapFactory:一个工具类,用于创建 ...
- Android 使用Bitmap将自身保存为文件,BitmapFactory从File中解析图片并防止OOM
1.使用Bitmap将自身保存为文件 public boolean saveBitmapAsFile(String name, Bitmap bitmap) { File saveFile = new ...
- zxing学习笔记 android入门
对于刚开始学习android开发的童鞋们来说,若有一个简单而又全面的android工程能来剖析,那就是再好不过了,zxing就是不错得例子. zxing的源码可以到google code上下载, ...
- Android入门(十六)调用摄像头相册
原文链接:http://www.orlion.ga/665/ 一.调用摄像头 创建一个项目ChoosePicDemo,修改activity_main.xml: <LinearLayout xml ...
- android 入门-android自定义控件
第一种:继承View 实现自己的属性 <com.cc.imagewithmarkersample.MyView android:id="@+id/myviewid" andr ...
- Android处理Bitmap的一些方法
http://www.it165.net/pro/html/201305/5795.html # 文件与Bitmap间的方法 1. 从文件载入Bitmap 01./** 02.* @brief 从文件 ...
- Android中Bitmap, Drawable, Byte,ID之间的转化
Android中Bitmap, Drawable, Byte,ID之间的转化 1. Bitmap 转化为 byte ByteArrayOutputStream out = new ByteArray ...
随机推荐
- DM9000C网卡驱动
目的:通过学习,掌握如何移植.编写DM9000C网卡驱动 一.概述: DM9000是一款高度集成低功耗快速以太网处理器,该芯片集成了MAC和PHY.DM9000可以和CPU直接连接,支持8位.16位和 ...
- 自己定义控件的onMeasure方法具体解释
在我们自己定义控件的时候可能你会用到onMeasure方法,以下就具体的给大家介绍一下这种方法: @Override protected void onMeasure(int widthMeasure ...
- D3.js加载csv和json数据
1.加载数据的基本命令 D3提供了方法可以对不同的数据类型进行加载,比如d3.text(), d3.xml(), d3.json(), d3.csv(), 和d3.html(). <!DOCTY ...
- [ Tomcat ] [ startup ] Tomcat 無法在時限內開啟問題
http://www.ewdna.com/2011/12/tomcat-server-in-eclipse-unable-to.html
- JavaScript--数据结构与算法之列表
3.1 列表的抽象数据类型定义 列表:一组有序的数据.每个列表中的数据称为元素.在JavaScript中列表的元素可以是任意的数据类型.列表中保存的元素没有事先的限定,实际使用时的元素数量受到程序内存 ...
- 动态链接库DLL的创建生成及调用
一.背景 最近在做CANTOUSB底层驱动的调用,是调用别人已经封装好的库,看不到别人写的源程序.程序中调用的是隐式调用即 x.h+x.lib+x.dll,其中DLL即是动态链接库(Dynamic L ...
- NIO专栏学习
http://blog.csdn.net/column/details/12993.html
- 几个经常使用的cmd命令
compmgmt.msc 计算机管理 devmgmt.msc 设备管理器 diskmgmt.msc 磁盘管理工具 dfrg.msc 磁盘碎片整理 eventvwr.msc 事件查看器 fsm ...
- ToggleButton控件
ToggleButton 两种状态 ·状态button -继承自CompoundButton ·主要属性:-Android:textOn -Android:textOff ·主要方法: ...
- ZOJ 题目3587 Marlon's String(KMP)
Marlon's String Time Limit: 2 Seconds Memory Limit: 65536 KB Long long ago, there was a coder n ...