2010-08-23 22:18 8569人阅读 评论(0) 收藏 举报
 分类:
android(94) 
 

目录(?)[+]

 

例说明

先前曾看过ImageView Widget的展示,虽可以将许多ImageView层层叠叠放在一起,再控制ImageView的图片来模拟动画的效果,但ImageView默认是没办法旋转的,那么要如何让ImageView产生旋转的效果呢?

要旋转ImageView其实很简单,先将前一次ImageView里的图片放入暂存Bitmap,接着再利用Bitmap.createBitmap来创建新的Bitmap对象,在创建新的Bitmap对象的同时,搭配Matrix对象里的setRotate()方法动态旋转新创建的Bitmap。然后,再将旋转好的Bitmap对象,以新构造的方式创建新的Bitmap对象,最后再“放入”ImageView中显示,就可以达到旋转ImageView的效果,这个范例的学习重点则在于如何操作BitmapFactory.decodeResource()方法来使用Matrix对图像的控制,为了让旋转能够通过事件来进行,所以在Layout中配置了两个Button Widget,以及一个ImageView Widget。当单击“向左旋转”按钮时,画面的小河马就会向左倾斜;当单击“向右旋转”按钮时,画面的小河马就会向右倾斜。

范例程序

src/irdc.ex04_24/EX04_24.java

程序设置了两个按钮,分别处理向左及向右旋转的语句,而为了防止旋转角度超过数值范围,所以默认参考值(ScaleAngle)向左最多为−5、向右则最多为5,再利用Matrix对象里的matrix.setRotate()方法,将5*ScaleAngle的计算结果传入作为参数,使其产生每次至少5°的变化,在−20°和20°之间。

Bitmap.createBitmap()方法所扮演的角色为产生暂存的Bitmap,使之每一次(单击按钮时)都“复制”来自原始图“mySourceBmp”的数据,自坐标(0,0)-(原图宽,原图高)复制成为新图,而由于createBitmap()方法的第六个参数可指定Matrix对象,这也就是本范例程序旋转画面的唯一关键。

/* import程序略 */

public class EX04_24 extends Activity

{

private Button mButton1;

private Button mButton2;

private TextView mTextView1;

private ImageView mImageView1;

private int ScaleTimes;

private int ScaleAngle;

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

mButton1 =(Button) findViewById(R.id.myButton1);

mButton2 =(Button) findViewById(R.id.myButton2);

mTextView1 = (TextView) findViewById(R.id.myTextView1);

mImageView1 = (ImageView) findViewById(R.id.myImageView1);

ScaleTimes = 1;

ScaleAngle = 1;

final Bitmap mySourceBmp = 

BitmapFactory.decodeResource(getResources(), R.drawable.hippo);

final int widthOrig = mySourceBmp.getWidth(); 

final int heightOrig = mySourceBmp.getHeight();

/* 程序刚运行,加载默认的Drawable */

mImageView1.setImageBitmap(mySourceBmp);

/* 向左旋转按钮 */

mButton1.setOnClickListener(new Button.OnClickListener()

{

@Override

public void onClick(View v)

{

// TODO Auto-generated method stub

ScaleAngle--;

if(ScaleAngle<-5)

{

ScaleAngle = -5;

}

/* ScaleTimes=1,维持1:1的宽高比例*/

int newWidth = widthOrig * ScaleTimes;

int newHeight = heightOrig * ScaleTimes;

float scaleWidth = ((float) newWidth) / widthOrig; 

float scaleHeight = ((float) newHeight) / heightOrig; 

Matrix matrix = new Matrix(); 

/* 使用Matrix.postScale设置维度 */

matrix.postScale(scaleWidth, scaleHeight);

/* 使用Matrix.postRotate方法旋转Bitmap*/

//matrix.postRotate(5*ScaleAngle);

matrix.setRotate(5*ScaleAngle);

/* 创建新的Bitmap对象 */

Bitmap resizedBitmap =

Bitmap.createBitmap

(mySourceBmp, 0, 0, widthOrig, heightOrig, matrix, true);

/**/

BitmapDrawable myNewBitmapDrawable =

new BitmapDrawable(resizedBitmap);

mImageView1.setImageDrawable(myNewBitmapDrawable);

mTextView1.setText(Integer.toString(5*ScaleAngle));

}

});

/* 向右旋转按钮 */

mButton2.setOnClickListener(new Button.OnClickListener()

{

@Override

public void onClick(View v)

{

// TODO Auto-generated method stub

ScaleAngle++;

if(ScaleAngle>5)

{

ScaleAngle = 5;

}

/* ScaleTimes=1,维持1:1的宽高比例*/

int newWidth = widthOrig * ScaleTimes;

int newHeight = heightOrig * ScaleTimes;

/* 计算旋转的Matrix比例 */

float scaleWidth = ((float) newWidth) / widthOrig; 

float scaleHeight = ((float) newHeight) / heightOrig; 

Matrix matrix = new Matrix(); 

/* 使用Matrix.postScale设置维度 */

matrix.postScale(scaleWidth, scaleHeight);

/* 使用Matrix.postRotate方法旋转Bitmap*/

//matrix.postRotate(5*ScaleAngle);

matrix.setRotate(5*ScaleAngle);

/* 创建新的Bitmap对象 */

Bitmap resizedBitmap =

Bitmap.createBitmap

(mySourceBmp, 0, 0, widthOrig, heightOrig, matrix, true);

/**/

BitmapDrawable myNewBitmapDrawable =

new BitmapDrawable(resizedBitmap);

mImageView1.setImageDrawable(myNewBitmapDrawable);

mTextView1.setText(Integer.toString(5*ScaleAngle));

}

});

}

}

扩展学习

Matrix类的设计,不仅是二维空间的结构,事实上,它原始的设计是3´3的矩阵,由于Matrix类并不需要构造器,因此在声明Matrix对象之后,可以调用reset()方法或set()方法产生新的矩阵,如同本范例的setRotate一样。

回来看看,我们在这个范例程序中,也放上了添加注释的语句matrix.postRotate(5*ScaleAngle),经测试后,无论是使用postRotate()方法或setRotate()方法,效果都是相同的,但较困惑的是Google的官方SDK文件中,所描述的postRotate()方法的原型如下:

boolean postRotate(float degrees, float px, float py)

经测试postRotate()方法并没有第二、第三个参数需要传递,这是在Android SDK 1.0_r2才发现的,未来可能会因为改版而有所改变。

另外,Matrix还有一个常用的postScale()方法,可通过矩阵的方式用以指定其缩放大小,其原型如下:

public boolean postScale(float sx, float sy, float px, float py)

使用的公式为:M' = S(sx, sy, px, py)* M,示意的片段程序如下。

final Bitmap mySourceBmp =

BitmapFactory.decodeResource(getResources(), R.drawable.hippo);

Matrix mx = new Matrix();

mx.postScale

(

(float)20/mySourceBmp.getWidth(),

(float)20/mySourceBmp.getHeight()

);

mySourceBmp = Bitmap.createBitmap

(bm, 0, 0, bm.getWidth(), bm.getHeight(), mx, true);

mImageView1.setImageBitmap(mySourceBmp);

转自:http://book.chinaunix.net/showart.php?id=8094

Bitmap与Matrix旋转ImageView的更多相关文章

  1. Android应用程序开发之图片操作(一)——Bitmap,surfaceview,imageview,Canvas

    Android应用程序开发之图片操作(一)——Bitmap,surfaceview,imageview,Canvas   1,Bitmap对象的获取 首先说一下Bitmap,Bitmap是Androi ...

  2. 我的Android进阶之旅------>Android通过使用Matrix旋转图片来模拟碟片加载过程

    今天实现了一个模拟碟片加载过程的小demo,在此展示一下.由于在公司,不好截取动态图片,因此就在这截取两张静态图片看看效果先. 下面简单的将代码列出来. setp1.准备两张用于旋转的图片,如下:lo ...

  3. android在假设绘制自己定义的bitmap,然后返回给ImageView

    先来说一下FontMetrics这个类.这个类是关于字符属性和測量的类 用图能够更精确的知道各个属性的含义: 我们在Layout中有一个ImageView,我们能够通过: <span style ...

  4. Android 学习笔记之Bitmap位图的旋转

    位图的旋转也可以借助Matrix或者Canvas来实现. 通过postRotate方法设置旋转角度,然后用createBitmap方法创建一个经过旋转处理的Bitmap对象,最后用drawBitmap ...

  5. Android学习笔记之Bitmap位图的旋转

    位图的旋转也可以借助Matrix或者Canvas来实现. 通过postRotate方法设置旋转角度,然后用createBitmap方法创建一个经过旋转处理的Bitmap对象,最后用drawBitmap ...

  6. Android Bitmap太大导致ImageView不显示的问题

    今天做我们的智能相冊的项目时,遇到了非常奇妙的问题,当照片太大时,导致ImageView.setImageBitmap不显示,上网上搜了非常多办法.感觉都不是那么靠谱.最后使用了简单粗暴的手段: // ...

  7. 054 Spiral Matrix 旋转打印矩阵

    给出一个 m x n 的矩阵(m 行, n 列),请按照顺时针螺旋顺序返回元素.例如,给出以下矩阵:[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ]]应该返回 [1,2, ...

  8. 成为Android高手必须掌握的28大项内容和10个建议

    (一)成为Android高手必须掌握的8项基本要求 [1] Android操作系统概述1. Android系统架构.           2. Android利用设计理念.           3. ...

  9. 成为Android高手必须掌握的8项基本要求

    [1] Android操作系统概述 1. Android系统架构. 2. Android利用设计理念. 3. Android 开源知识. 4. Android 参考网站与权威信息.[2] Androi ...

随机推荐

  1. web.py 学习(二)Worker

    Rocket Server 启动一个线程监听客户端的连接,收到连接将连接放置到队列中.线程池中的Worker会以这个连接进行初始化.Rocket中Worker的基类是: class Worker(Th ...

  2. java 内省

    用内省来操作Bean会给程序带来很大的便利,特别是在很大的实体对象的时候,在其属性很多的时候要为其赋值的时候, package com.bean; public class User { privat ...

  3. webapi中Route标签定义可选参数

    Optional URI Parameters and Default Values You can make a URI parameter optional by adding a questio ...

  4. Gentoo本地化设置--Locale系统介绍

    locale是什么? 一份Locale是一组信息的集合,大多数程序利用它来确定特定的国家和语言设置.这些locale以及它们包含的数据是系统库的一部分,可以在大多数系统中的/usr/share/loc ...

  5. text绑定(The "text" binding)

    目的 text绑定可以使你传递的参数做为文本显示到相关的DOM元素里. 一般会用在如<span>或者<em>这类元素来显示文本,但从技术来讲它可以绑定到任何元素. 示例 Tod ...

  6. CSS居中方法

    css居中方法非常多,根据工作的实际情况采用恰当方法,可取到事半功倍的效果. 就常见的一些居中方法整理如下: 代码如下: <div class="con"> <d ...

  7. IP子网掩码格式转换

    def exchange_maskint(mask_int): bin_arr = [' for i in range(32)] for i in range(mask_int): bin_arr[i ...

  8. IOS应用的国际化

    IOS应用的国际化,主要分为3个部分: Info.plist 文件的国际化 .xib文件的国际化 .m文件的国际化 下面我就来一一说明. Info.plist 文件的国际化我们使用Xcode 4.5 ...

  9. TCP拥塞处理—Congestion Handing

      TCP拥塞处理-Congestion Handing 1 慢启动 2 拥塞避免 3 快重传/拥塞发生(拥塞发生时的快速重传) 4 快恢复

  10. 9---PIP 管理工具的使用

    Python 不仅有强大的内置模块,还提供强大的三方模块. 官方网站: https://pypi.python.org/pypi 要适用三方的模块需要使用pip管理工具. 1.在安装pip前,请确认w ...