Android画图学习总结(二)——Bitmap+Canvas

通过前一篇的学习,对Android 画图核心部分有了一定的了解,后面篇幅,我们将详细介绍Android中的各种画图对象的使用,首先介绍我们最常用的Bitmap(位图)。位图是我们开发中最常用的资源,毕竟一个漂亮的界面对用户是最有吸引力的。按照对位图的操作,分为以下几个功能分别介绍:

  1. 从资源中获取位图
  2. 获取位图的信息
  3. 显示位图
  4. 位图缩放
  5. 位图旋转

1. 从资源中获取位图

在前一篇幅介绍了:先获取Resource,然后可以通过资源ID获取Drawable,也可以通过资源ID获取资源文件的数据流。使用第一种方法比较容易,下面详细说明第二种方法。通过Resource的函数:InputStream  openRawResource(int id)获取得到资源文件的数据流后,也可以通过2种方法来获取Bitmap,如下:

使用BitmapDrawable

(A Drawable that wraps a bitmap and can be tiled, stretched, or aligned.)

  1. 使用BitmapDrawable (InputStream is)构造一个BitmapDrawable;
  2. 使用BitmapDrawable类的getBitmap()获取得到位图;

BitmapDrawable也提供了显示位图等操作

使用BitmapFactory

(Creates Bitmap objects from various sources, including files, streams, and byte-arrays.)

  1. 使用BitmapFactory类decodeStream(InputStream is)解码位图资源,获取位图

BitmapFactory的所有函数都是static,这个辅助类可以通过资源ID、路径、文件、数据流等方式来获取位图。

以上方法在编程的时候可以自由选择,在Android SDK中说明可以支持的图片格式如下:png (preferred), jpg (acceptable), gif (discouraged),虽然bmp格式没有明确说明,但是在Android SDK Support Media Format中是明确说明了。

2. 获取位图的信息

要获取位图信息,比如位图大小、是否包含透明度、颜色格式等,获取得到Bitmap就迎刃而解了,这些信息在Bitmap的函数中可以轻松获取到。Android SDK中对Bitmap有详细说明,阅读起来也比较容易,不在此详细说明,这里只是辅助说明以下2点:

  • 在Bitmap中对RGB颜色格式使用Bitmap.Config定义,仅包括ALPHA_8、ARGB_4444、ARGB_8888、RGB_565,缺少了一些其他的,比如说RGB_555,在开发中可能需要注意这个小问题;
  • Bitmap还提供了compress()接口来压缩图片,不过AndroidSAK只支持PNG、JPG格式的压缩;其他格式的需要Android开发人员自己补充了。

3. 显示位图

显示位图需要使用核心类Canvas,可以直接通过Canvas类的drawBirmap()显示位图,或者借助于BitmapDrawable来将Bitmap绘制到Canvas。具体如何显示位图不是主要的问题,主要问题是如何获取Canvas,参考Snake中的方法,做了个简单的例子testView,代码如下:

testActivity:

package testView.moandroid;

import android.app.Activity;
import android.os.Bundle;

public class testActivity extends Activity {
	private testView mTestview;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mTestview = (testView) findViewById(R.id.testView);
        mTestview.initBitmap(320,240,0xcccccc);
    }
}

testView:

package testView.moandroid;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.Bitmap.Config;
import android.util.AttributeSet;
import android.view.View;

public class testView extends View {
	private Bitmap  mbmpTest=null;
	private final Paint mPaint = new Paint();
	private final String mstrTitle="感受Android带给我们的新体验";
	public testView(Context context, AttributeSet attrs, int defStyle)
	{
	     super(context, attrs, defStyle);
	     mPaint.setColor(Color.GREEN);
	}
	 public testView(Context context, AttributeSet attrs) 
	 {
	     super(context, attrs);
	     mPaint.setColor(Color.GREEN);
	 }
	 
	public boolean initBitmap(int w,int h,int c)
	{
		mbmpTest = Bitmap.createBitmap(w,h, Config.ARGB_8888);
		Canvas canvas = new Canvas(mbmpTest);  
		canvas.drawColor(Color.WHITE);
		Paint p = new Paint();
		String familyName = "宋体";
		Typeface font = Typeface.create(familyName,Typeface.BOLD);
		p.setColor(Color.RED);
		p.setTypeface(font);
		p.setTextSize(22);  
		canvas.drawText(mstrTitle,0,100,p);
		return true;
	}

	@Override
    public void onDraw(Canvas canvas) 
	{
		 super.onDraw(canvas); 
		 /*if(mbmpTest!=null)
		 {
		     Rect rtSource = new Rect(0,0,320,240);
		     Rect rtDst = new Rect(0,0,320,240);
		     canvas.drawBitmap(mbmpTest, rtSource,rtDst, mPaint);
		 }*/
		 if(mbmpTest!=null)
		 {
		   Matrix matrix = new Matrix();
           //matrix.postScale(0.5f, 0.5f);
           matrix.setRotate(90,120,120);
           canvas.drawBitmap(mbmpTest, matrix, mPaint);
		 } 
    }
}
	

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
 <testView.moandroid.testView
	 android:id="@+id/testView"
	 android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     tileSize="12"/>
</FrameLayout>

testView例子介绍:其包含2个类testActivity,testView;testActivity继承与Activity,testView继承与View。这个例子就是将testView直接作为testActivity的窗口,这样我们就可以直接在testView画图了。具体如何实现的,请大家参考testActivity的onCreate()中的代码,以及layout\main.xml中的设置。在testView的onDraw()直接画图,结果在例子程序运行后就可以直接在界面上显示了。

4. 位图缩放

位图的缩放,在Android SDK中提供了2种方法:

  • 将一个位图按照需求重画一遍,画后的位图就是我们需要的了,与位图的显示几乎一样:
    drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
  • 在原有位图的基础上,缩放原位图,创建一个新的位图:
    createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)

第2种方法一看就明白,对于第一种方法,举个简单的例子来说明:

int w = 320,h = 240;
String mstrTitle = “感受Android带给我们的新体验”;
Bitmap mbmpTest = Bitmap.createBitmap(w,h, Config.ARGB_8888);
Canvas canvasTemp = new Canvas(mbmpTest);
canvasTemp.drawColor(Color.WHITE);
Paint p = new Paint();
String familyName = “宋体”;
Typeface font = Typeface.create(familyName,Typeface.BOLD);
p.setColor(Color.RED);
p.setTypeface(font);
p.setTextSize(22);
canvasTemp.drawText(mstrTitle,0,100,p);

显示位图mbmpTest,就会发现一张320×240、白色背景、红色“宋体”文字的图片,如下:


这个例子没有位图缩放的任何操作?的确,但是这是我在想如何写个简单的位图缩放的小程序时,最先想到的。看完这个例子,我想你就应该明白如何实现位图的缩放了。不要小瞧了这个例子,虽然与位图缩放关系不大,但是却可以让你理解位图缩放的本质:将原始位图按照需求显示出来,就创造了一张新的位图。

5. 位图旋转

位图的旋转,离不开Matrix。Matrix在线性代数中都学习过,Android SDK提供了Matrix类,可以通过各种接口来设置矩阵。结合上面的例子程序,将位图缩放例子程序在显示位图的时候前,增加位图旋转功能,修改代码如下:

Matrix matrix = new Matrix();
//matrix.postScale(0.5f, 0.5f);
matrix.setRotate(90,120,130);
canvas.drawBitmap(mbmpTest, matrix, mPaint);

旋转后的位图显示如下:


除了这种方法之外,我们也可以在使用Bitmap提供的函数如下:
public static Bitmap createBitmap (Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter),在原有位图旋转的基础上,创建新位图。

总结说明

对位图的操作,结合Android SDK中的类,详细的介绍完了。最后还需要强调的是:这篇文章只是对Android SDK中代码阅读分析,它代替不了你阅读Android SDK,深入的学习还是要仔细的阅读Android SDK。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值