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

来源:互联网 发布:淘宝特惠囤 编辑:程序博客网 时间:2024/05/21 21:43
使用Matrix控制变换
Matrix是Android的一个矩形工具类,它与其它API结合来控制图形、组件的变换。使用步骤如下:
  1. 获取Matrix对象,新建或获取已封装的Matrix
  2. 调用Matrix方法进行平移、旋转、缩放、倾斜等
  3. 将程序对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进行扭曲
示例代码如下:
publicclassMeshTest extends Activity{
privateBitmap bitmap;
@Override
publicvoidonCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(
newMyView(this, R.drawable.jinta));
}
privateclassMyView extends View
{
privatefinalintWIDTH= 20;
privatefinalintHEIGHT= 20;
privatefinalintCOUNT= (WIDTH+ 1) * (HEIGHT+ 1);
privatefinalfloat[] verts = new float[COUNT* 2];
privatefinalfloat[]orig= new float[COUNT* 2];
publicMyView(Context context, int drawableId)
{
super(context);
setFocusable(
true);
bitmap= BitmapFactory.decodeResource(getResources()
,drawableId);
floatbitmapWidth = bitmap.getWidth();
floatbitmapHeight = bitmap.getHeight();
intindex = 0;
for(inty = 0; y <= HEIGHT; y++)
{
floatfy = bitmapHeight * y / HEIGHT;
for(intx = 0; x <= WIDTH; x++)
{
floatfx = 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
protectedvoidonDraw(Canvas canvas)
{
canvas.drawBitmapMesh(
bitmap,WIDTH,HEIGHT
,
verts, 0,null, 0,null);
}
privatevoidwarp(floatcx, float cy)
{
for(inti = 0; i< COUNT * 2;i += 2)
{
floatdx = cx - orig[i +0];
floatdy = cy - orig[i + 1];
floatdd = dx * dx + dy * dy;
floatd = (float) Math.sqrt(dd);
floatpull = 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
publicbooleanonTouchEvent(MotionEvent event)
{
warp(event.getX(), event.getY());
returntrue;
}
}
}


使用Shader填充图形
Shader本身是个抽象类,它提供如下实现类
BitmapShader
LinearGradient
RadialGradient
SweepGradient
ComposeShader

0 0
原创粉丝点击