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 ...
随机推荐
- ArcGIS “Error HRESULT E_FAIL has been returned from a call to a COM component.” 异常的解决
错误提示内容: {System.Runtime.InteropServices.COMException (0x80004005): Error HRESULT E_FAIL has been ret ...
- [PWA] Deal with caches in PWA
The takeway is to know when we should cache the content? When we should clean the caches? 1. When sh ...
- [Express] Upload Files with Express
In this lesson we create a new Express web server app for handling file uploads and persisting them ...
- 运行 CMD 时,參数加引號常见问题
在调用 CMD 时.如脚本中用 WScript.Shell 调用. 假设參数中有包括空格的长路径名时,必需要加引號才干正确被识别. 是的,大家都知道要加引號.但怎么加却easy被误解.这个问题,不时地 ...
- widget-移除底部小部件内容
今天有一个要求,就是在调出手机窗口小部件的时候,让其中的某些小部件不显示.折腾了好久,虽然不知道原理,最终还是实现了屏蔽其中个别小部件的方法.记录下来 要想屏蔽底部小部件的显示,只需要把相关的类跟广播 ...
- 《三》Java IO 字节输入输出流
那么这篇博客我们讲的是字节输入输出流:InputStream.OutputSteam(下图红色长方形框内),红色椭圆框内是其典型实现(FileInputSteam.FileOutStream) ...
- CISP/CISA 每日一题 九(2017-11-30 09:25)
电子银行风险管理责任: 1.风险管理是董事会和高级管理层的责任 2.实施技术是信息技术高级管理层的责任 3.测量和监控风险是经营管理层的责任 管理层在实施一个新的电子银行应用程序之前要 ___ ...
- 数学定理证明机械化的中国学派(II)
所谓"学派"是指:存在一帮人,具有同样或接近的学术观点或学术立场,採用某种特定的"方法"(或途径),在一个学术方向上共同开展工作.而且做出了相当有迎影响的学术成 ...
- OR1200指令Cache使用举例
下面内容摘自<步步惊芯--软核处理器内部设计分析>一书 12.4 ICache中的特殊寄存器 通过ICache的接口可知其具有特殊寄存器,而且是不可读的特殊寄存器,OR1200处理器中IC ...
- c3p0的经常使用配置方式
1:第一种方式很easy c3p0.driverClass=com.mysql.jdbc.Driver c3p0.jdbcUrl=jdbc:mysql://localhost:3308/databas ...