可揉动的图片

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
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值