Android(Java)を始める – 画像の自由変形

Filed under Android, Java

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;
	}
}

Post a Comment

Your email is never published nor shared.