可揉动的图片

来源:互联网 发布:免费叫卖录音软件 编辑:程序博客网 时间:2024/06/05 15:50
public class MainActivity extends AppCompatActivity{    private Bitmap bitmap = null;    @Override    protected void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        setContentView(new MyView(this,R.drawable.dog2));    }    private class MyView extends View    {        //定义两个变量,这两个变量指定该图片的横向和纵向被划分为20格        private final int WIDTH = 20;        private final int HEIGHT = 20;        //记录该图片包含441个顶点        private final int COUNT = (WIDTH + 1)*(HEIGHT+1);        //定义一个数组,保存Bitmap上面的21*21个点的坐标        private final float[] verts =  new float[COUNT*2];        //定义一个数组,记录bitmap上的21*21个点经过扭曲后的坐标        //对图片进行扭曲的关键就是修改该数组里的元素的值        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、verts数组,两个数组都保留了21*21个点的x,y坐标                    orig[(index * 2)] = verts[(index * 2)] = fx;                    orig[index*2 + 1] = verts[index*2 + 1] = fy;                    index += 1;                }            }            setBackgroundColor(Color.WHITE);        }        @Override        protected void onDraw(Canvas canvas)        {            //对bitmap按verts数组进行扭曲            //从第一个点(由第5个参数0控制)开始扭曲            canvas.drawBitmapMesh(bitmap, WIDTH, HEIGHT, verts, 0, null, 0, null);        }        private void wrap(float cx,float cy)        {            for(int i = 0;i<COUNT*2; i+=2)            {                float dx = cx -orig[i];                float dy = cy - orig[i+1];                float dd = dx*dx + dy*dy;                //计算每个坐标点与当前点(cx,cy)之间的距离                float d = (float) Math.sqrt(dd);                //计算扭曲度,距离当前点(cx,cy)越远,扭曲度越小                float pull = 80000/ (dd*d);                if (pull >= 1)                {                    verts[i] = cx;                    verts[i+1] = cy;                }                else                {                    verts[i] = orig[i] + dx*pull;                    verts[i+1] = orig[i+1] + dy*pull;                }            }            //通知View组件重绘            invalidate();        }        @Override        public boolean onTouchEvent(MotionEvent event)        {            wrap(event.getX(),event.getY());            return true;        }    }}

0 0