zoukankan      html  css  js  c++  java
  • Bitmap与Matrix旋转ImageView

     

    Bitmap与Matrix旋转ImageView 

    标签: matrixfloatbutton测试importlayout
    2010-08-23 22:18 8569人阅读 评论(0) 收藏 举报
     分类:
     

    目录(?)[+]

     

    例说明

    先前曾看过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

  • 相关阅读:
    Longest Valid Parentheses
    [转载]ios入门篇 -hello Word(1)
    EXTJS 4 动态grid
    Spring AOP JPA
    Jchart 演示
    HSQLDB JPA GeneratedValue
    Antlr 练习
    回火方程
    URL decode 解决中文目录的乱码问题
    Arduino IIC lcd1602
  • 原文地址:https://www.cnblogs.com/qingchen1984/p/5044652.html
Copyright © 2011-2022 走看看