
Androidの勉強中。
ドラッグで画像を自由に変形出来ます。
画像の自由変形にはCanvasが持つdrawBitmapMeshメソッドを利用してます。
メッシュの座標の配列を指定して画像を描画出来るっぽいです。
以下、今回のソースです。
Main.javaのソース。
package jp.sakef;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
public class Main extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(new MainView(this));
}
}
MainView.javaのソース。
package jp.sakef;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MainView extends SurfaceView implements SurfaceHolder.Callback, Runnable
{
private SurfaceHolder holder=null;
private Thread thread=null;
private int isDrag;
private Paint paint;
private Bitmap bmp;
private float[] vers;
private ArrayList<Circle> container;
public MainView(Context context)
{
super(context);
getHolder().addCallback(this);
isDrag = -1;
container = new ArrayList<Circle>();
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.rgb(200, 0, 0));
bmp = BitmapFactory.decodeResource(getResources(),R.drawable.img);
}
public void surfaceDestroyed(SurfaceHolder holder)
{
thread = null;
}
public void surfaceCreated(SurfaceHolder holder)
{
this.holder = holder;
thread = new Thread(this);
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
// 画像の四隅に円を配置
Circle c1 = new Circle(25f, 10f, 10f);
container.add(c1);
Circle c2 = new Circle(25f, bmp.getWidth()+10, 10f);
container.add(c2);
Circle c3 = new Circle(25f, 10f, bmp.getHeight()+10);
container.add(c3);
Circle c4 = new Circle(25f, bmp.getWidth()+10, bmp.getHeight()+10);
container.add(c4);
// 座標の入った配列を作成
vers = new float[]{c1.x, c1.y, c2.x, c2.y, c3.x, c3.y, c4.x, c4.y};
if(thread != null) thread.start();
}
public void run()
{
while (thread != null)
{
// 塗りつぶし
Canvas canvas = holder.lockCanvas();
canvas.drawColor(Color.BLACK);
// 画像を描画
canvas.drawBitmapMesh(bmp, 1, 1, vers, 0, null, 0, null);
// 円を描画
int size = container.size();
for(int i=0 ; i< size ; i++)
{
Circle c = container.get(i);
canvas.drawCircle(c.x, c.y, c.radius, paint);
}
holder.unlockCanvasAndPost(canvas);
}
}
// クリック時のイベント
public boolean onTouchEvent(MotionEvent event)
{
float x = event.getX();
float y = event.getY();
// 画面のタッチ時
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
int size = container.size();
for(int i=0 ; i<size ; i++)
{
Circle c = container.get(i);
if((c.x-x)*(c.x-x) + (c.y-y)*(c.y-y) < c.radius*c.radius)
{
isDrag = i;
break;
}
}
}
// ドラッグ時
else if (event.getAction() == MotionEvent.ACTION_MOVE)
{
if(isDrag != -1)
{
Circle c = container.get(isDrag);
c.x = x;
c.y = y;
vers[isDrag*2] = c.x;
vers[isDrag*2+1] = c.y;
}
}
// 指を離したとき
else if(event.getAction() == MotionEvent.ACTION_UP)
{
isDrag = -1;
}
return true;
}
}
Circle.javaのソース。
package jp.sakef;
public class Circle
{
public float radius;
public float x;
public float y;
public Circle(float radius, float x, float y)
{
this.radius = radius;
this.x = x;
this.y = y;
}
}