您的位置:首页 > 移动开发 > Android开发

Android的图形与图像处理之二 图形特效处理

2015-01-31 17:40 381 查看
使用Matrix控制变换
Matrix是Android的一个矩形工具类,它与其它API结合来控制图形、组件的变换。使用步骤如下:
获取Matrix对象,新建或获取已封装的Matrix
调用Matrix方法进行平移、旋转、缩放、倾斜等
将程序对Matrix所做的变换应用到指定图像或组件
Matrix变换方法有:
setTranslate(float dx, float dy)
控制Matrix进行平移
setSkew(float kx, float ky, float px, float py)
控制Matrix以px、py为轴心进行倾斜,kx、ky为X、Y方向上的倾斜距离
setSkew(float kx, float ky)
setRotate(float degrees)
setRotate(float degrees,float px, float py)

旋转角度degree,旋转轴心(px, py)
setScale(float sx, float sy)
缩放,sx、sy控制X、Y方向上的缩放比例
setScale(float sx,float sy, float px, float py)
Canvas提供了drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint),在绘制Bitmap时应用Matrix上的变换
示例代码:
(自定义了一个View,该View可检测到用户键盘事件,当用户单击手机方向键时,该自定义View会用Matrix对绘制的图形进行旋转、倾斜)

借助Bitmap的createBitmap方法可以“挖取”源位图的其中一块,这样可以再程序中通过定时器控制不断地“挖取”源位图不同位置的块,从而给用户看到背景移动“假象”
例如,“雷电”中,为了给用户造成飞机不断向下飞行的错觉,可以通过这种方式控制背景图片不断下移,来使用户产生错觉
示例代码:
main.xml:
public class MoveBack extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this));
    }
    class MyView extends View
    {
         final int BACK_HEIGHT = 1700;
         private Bitmap back;
         private Bitmap plane;
         final int WIDTH=320;
         final int HEIGHT=480;
         private int startY = BACK_HEIGHT - HEIGHT;
         public MyView(Context context)
         {
              super(context);
              back = BitmapFactory.decodeResource(context.getResources()
                        , R.drawable.back_img);
              plane = BitmapFactory.decodeResource(context.getResources()
                        , R.drawable.plane);
              final Handler handler = new Handler()
              {
                   //定义错误,导致无法移动
//                   public void HandleMessage(Message msg)
                   public void handleMessage(Message msg)
                   {
                        if (msg.what == 0x123)
                        {
                             if(startY <= 0)
                             {
                                  startY = BACK_HEIGHT - HEIGHT;
                             }
                             else
                             {
                                  startY -= 3;
                             }
                        }
                        invalidate();
                   }
              };
              new Timer().schedule(new TimerTask()
              {
                   @Override
                   public void run()
                   {
                        handler.sendEmptyMessage(0x123);
                   }
              },0,100);
         }
         @Override
         public void onDraw(Canvas canvas)
         {
              Bitmap bitmap2 = Bitmap
                        .createBitmap(back, 0 , startY, WIDTH, HEIGHT);
              canvas.drawBitmap(bitmap2, 0, 0,null);
              canvas.drawBitmap(plane, 160, 360,null);
         }
    }

}

使用drawBitmapMesh扭曲图像
Canvas提供了一个drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint)方法对bitmap进行扭曲。(水波荡漾、风吹旗帜)
bitmap

源位图
meshWidth

在横向上把该源位图划分成多少格
meshHeight

verts

该参数是一个长度为(meshWidth+1)*(meshHeight+1)*2的数组,它记录了扭曲后的位图各“顶点”位置。虽然它是一位数组,实际上记录的是(x0,y0),(x1,y1)...
vertOffset

控制verts中从第几个数组才开始对bitmap进行扭曲
示例代码如下:
public
class
MeshTest
extends Activity{
private
Bitmap
bitmap;
@Override
public
void
onCreate(Bundle savedInstanceState)

{
super.onCreate(savedInstanceState);

setContentView(new
MyView(this, R.drawable.jinta));

}
private
class
MyView
extends View

{
private
final
int
WIDTH
= 20;
private
final
int
HEIGHT
= 20;
private
final
int
COUNT
= (WIDTH
+ 1) * (HEIGHT
+ 1);
private
final
float
[]
verts =
new
float[COUNT
* 2];
private
final
float[]
orig
=
new
float[COUNT
* 2];
public
MyView(Context context,
int drawableId)

{
super(context);

setFocusable(true);
bitmap
= BitmapFactory.decodeResource(getResources()

,drawableId);
float
bitmapWidth =
bitmap.getWidth();
float
bitmapHeight =
bitmap.getHeight();
int
index = 0;
for(int
y = 0; y <=
HEIGHT; y++)

{
float
fy = bitmapHeight * y /
HEIGHT;
for(int
x = 0; x <=
WIDTH; x++)

{
float
fx = bitmapWidth * x/
WIDTH;
orig[index*2 + 0] =
verts[index *2 + 0] = fx;
orig[index*2 + 1] =
verts[index *2 + 1] = fy;

index += 1;

}

}

setBackgroundColor(Color.WHITE);

}
@Override
protected
void
onDraw(Canvas canvas)

{

canvas.drawBitmapMesh(bitmap,
WIDTH,
HEIGHT

, verts, 0,
null, 0,
null);

}
private
void
warp(float
cx,
float cy)

{
for(int
i = 0; i<
COUNT * 2;i += 2)

{
float
dx = cx -
orig[i +0];
float
dy = cy -
orig[i + 1];
float
dd = dx * dx + dy * dy;
float
d = (float) Math.sqrt(dd);
float
pull = 80000/ ((float)(dd * d));
if
(pull >= 1)

{
verts[i+0] = cx;
verts[i+1] = cy;

}
else

{
verts[i+0] =
orig[i + 0] + dx* pull;
verts[i+1] =
orig[i + 1] + dy* pull;

}

}

invalidate();

}
@Override
public
boolean
onTouchEvent(MotionEvent event)

{

warp(event.getX(), event.getY());
return
true;

}

}

}

使用Shader填充图形
Shader本身是个抽象类,它提供如下实现类
BitmapShader
LinearGradient
RadialGradient
SweepGradient
ComposeShader
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: