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;
}
}
}
可揉动的图片
最新推荐文章于 2022-08-31 18:08:20 发布