网站开发与移动开发

博客园 首页 新随笔 管理

上一篇Android画图之Matrix(一) 讲了一下Matrix的原理和运算方法,涉及到高等数学,有点难以理解。还好Android里面提供了对Matrix操作的一系

列方便的接口。


    Matrix的操作,总共分为translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种,每一种变换在

Android的API里都提供了set, post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。


    set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。


    post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。例如,要将一个图片旋
转30度,然后平移到(100,100)的地方,那么可以这样做:

Java代码 

Matrix m = new Matrix();  

  

m.postRotate(30);  

  

m.postTranslate(100, 100);    

 

 

这样就达到了想要的效果。


    pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。例如上面的例子,如果用pre的话

,就要这样:

Java代码 

Matrix m = new Matrix();  

  

m.setTranslate(100, 100);  

  

m.preRotate(30);  

    旋转、缩放和倾斜都可以围绕一个中心点来进行,如果不指定,默认情况下,是围绕(0,0)点来进行。

 

    下面给出一个例子。

Java代码 

package chroya.demo.graphics;  

  

import android.content.Context;  

import android.graphics.Bitmap;  

import android.graphics.Canvas;  

import android.graphics.Matrix;  

import android.graphics.Rect;  

import android.graphics.drawable.BitmapDrawable;  

import android.util.DisplayMetrics;  

import android.view.MotionEvent;  

import android.view.View;  

  

public class MyView extends View {  

      

    private Bitmap mBitmap;  

    private Matrix mMatrix = new Matrix();  

      

    public MyView(Context context) {  

        super(context);  

        initialize();  

    }  

  

    private void initialize() {  

          

        Bitmap bmp = ((BitmapDrawable)getResources().getDrawable(R.drawable.show)).getBitmap();  

        mBitmap = bmp;  

        /*首先,将缩放为100*100。这里scale的参数是比例。有一点要注意,如果直接用100/ 

bmp.getWidth()的话,会得到0,因为是整型相除,所以必须其中有一个是float型的,直接用100f就好。*/  

        mMatrix.setScale(100f/bmp.getWidth(), 100f/bmp.getHeight());  

                //平移到(100,100)处  

        mMatrix.postTranslate(100, 100);  

                //倾斜x和y轴,以(100,100)为中心。  

        mMatrix.postSkew(0.2f, 0.2f, 100, 100);  

    }  

      

    @Override protected void onDraw(Canvas canvas) {  

//      super.onDraw(canvas);  //如果界面上还有其他元素需要绘制,只需要将这句话写上就行了。  

          

        canvas.drawBitmap(mBitmap, mMatrix, null);  

    }  

}  

 运行效果如下:

    红色的x和y表示倾斜的角度,下面是x,上面是y。看到了没,Matrix就这么简单 

 

 

 

//////////

旋转图片的几种方式

文章分类:移动开发

一、每次根据旋转矩阵从原位图创建出旋转后的新位图。但是缺点就是要船舰新的位图。 
// createa matrix for the manipulation 
Matrix matrix = new Matrix(); 
// rotate the Bitmap 
matrix.postRotate(45); 

// recreate the new Bitmap 
Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, 
width, height, matrix, true); 

// make a Drawable from Bitmap to allow to set the BitMap 
// to the ImageView, ImageButton or what ever 
BitmapDrawable bmd = new BitmapDrawable(resizedBitmap); 

二、将旋转图片转为旋转画布。效率较高。Android官方Demo:LunarLander正是旋转画布,从而达到旋转图片,但是从效果上看,有些失真。(旋转图片时,一般旋转中心为图片的中心。) 
(旋转方向为顺时针,若角度为负则为逆时针) 

//注意画布的状态保存和恢复 
canvas.save(); 
//参数分别为:旋转角度,图片X中心,图片Y中心。 
canvas.rotate(angle, getCenterX(),getCenterY()); 
spriteImage.setBounds(bounds); 
spriteImage.draw(canvas); 
canvas.restore();

///////////////////

Android画图并保存图片

项目中遇到了一个图片合成的问题,搞很长时间也没搞定,最后使用Canvas和Bitmap解决了画图的问题。

 

Canvas是一个画布,你可以建立一个空白的画布,就直接new一个Canvas对象,不需要参数。

也可以先使用BitmapFactory创建一个Bitmap对象,作为新的Canvas对象的参数,也就是说这个画布不是空白的,

如果你想保存图片的话,最好是Bitmap是一个新的,而不是从某个文件中读入进来的,或者是Drawable对象。

 

然后使用Canvas画第一张图上去,在画第二张图上去,最后使用Canvas.save(int flag)的方法进行保存,注意save方法里面的参数可以保存单个图层,

如果是保存全部图层的 话使用 save( Canvas.ALL_SAVE_FLAG )。

 

最后所有的信息都会保存在第一个创建的Bitmap中。代码如下:

/** 

    * create the bitmap from a byte array 

    * 

    * @param src the bitmap object you want proecss 

    * @param watermark the water mark above the src 

    * @return return a bitmap object ,if paramter's length is 0,return null 

    */  

   private Bitmap createBitmap( Bitmap src, Bitmap watermark )  

   {  

       String tag = "createBitmap";  

       Log.d( tag, "create a new bitmap" );  

       if( src == null )  

       {  

           return null;  

       }  

  

       int w = src.getWidth();  

       int h = src.getHeight();  

       int ww = watermark.getWidth();  

       int wh = watermark.getHeight();  

       //create the new blank bitmap  

       Bitmap newb = Bitmap.createBitmap( w, h, Config.ARGB_8888 );//创建一个新的和SRC长度宽度一样的位图  

       Canvas cv = new Canvas( newb );  

       //draw src into  

       cv.drawBitmap( src, 0, 0, null );//在 0,0坐标开始画入src  

       //draw watermark into  

       cv.drawBitmap( watermark, w - ww + 5, h - wh + 5, null );//在src的右下角画入水印  

       //save all clip  

       cv.save( Canvas.ALL_SAVE_FLAG );//保存  

       //store  

       cv.restore();//存储  

       return newb;  

   }  

 

 对图片进行缩小的方法:

Java代码 

/** 

    * lessen the bitmap 

    * 

    * @param src bitmap 

    * @param destWidth the dest bitmap width 

    * @param destHeigth 

    * @return new bitmap if successful ,oherwise null 

    */  

   private Bitmap lessenBitmap( Bitmap src, int destWidth, int destHeigth )  

   {  

       String tag = "lessenBitmap";  

       if( src == null )  

       {  

           return null;  

       }  

       int w = src.getWidth();//源文件的大小  

       int h = src.getHeight();  

       // calculate the scale - in this case = 0.4f  

       float scaleWidth = ( ( float ) destWidth ) / w;//宽度缩小比例  

       float scaleHeight = ( ( float ) destHeigth ) / h;//高度缩小比例  

       Log.d( tag, "bitmap width is :" + w );  

       Log.d( tag, "bitmap height is :" + h );  

       Log.d( tag, "new width is :" + destWidth );  

       Log.d( tag, "new height is :" + destHeigth );  

       Log.d( tag, "scale width is  :" + scaleWidth );  

       Log.d( tag, "scale height is  :" + scaleHeight );  

       Matrix m = new Matrix();//矩阵  

       m.postScale( scaleWidth, scaleHeight );//设置矩阵比例  

       Bitmap resizedBitmap = Bitmap.createBitmap( src, 0, 0, w, h, m, true );//直接按照矩阵的比例把源文件画入进行  

       return resizedBitmap;  

   }  

posted on 2012-02-27 19:55  txf2004  阅读(271)  评论(0编辑  收藏  举报