drawLine, drawPath를 써보자

Posted by ITPangPang
2016. 9. 19. 22:48 안드로이드(android)/캔버스(Canvas)


drawLine, drawPath를

써보자



ㆍ 이번에는 drawLine과 drawPath를 써보도록 하겠습니다


drawLine은 스펠링 그대로 선을 하나 그려주는 것이고

    drawPath는 개발자가 경로를 정해준 후에 그 경로대로

    canvas에 그리는 것입니다


ㆍ 앱마다 다르겠지만 저는 drawLine은 공부할때만 써보고

    실제로 개발하는 앱에는 적용해본적이 없습니다.. ㅠ.ㅠ


ㆍ 대신에 drawPath는 정말.. 질리도록 써봤습니다. 

    Custom Crop을 구현해야 되서 터치와 ondraw의 만남..



어쨋든

언제 쓰게 될지 모르니

drawLine을 먼저 써보도록

하겠습니다.


코드는 지난번에 썻던 코드를

가져다가 수정만해서 사용하도록

하겠습니다.


public class MainActivity extends AppCompatActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
ViewEx viewEx = new ViewEx(this);
setContentView(viewEx);
}

protected class ViewEx extends View
{
public ViewEx(Context context)
{
super(context);
}
public void onDraw(Canvas canvas)
{
canvas.drawColor(Color.BLACK);

Paint MyPaint = new Paint();
MyPaint.setColor(Color.BLUE);
MyPaint.setStrokeWidth(30f);
canvas.drawPoint(360, 640, MyPaint);

MyPaint.setStrokeWidth(10f);
MyPaint.setStyle(Paint.Style.STROKE);
MyPaint.setColor(Color.RED);
canvas.drawRect(200, 200, 300, 400, MyPaint);

MyPaint.setStrokeWidth(5f);
MyPaint.setStyle(Paint.Style.FILL);
MyPaint.setColor(Color.GRAY);
canvas.drawRect(400, 400, 600, 600, MyPaint);

MyPaint.setStrokeWidth(20f);
MyPaint.setStyle(Paint.Style.FILL_AND_STROKE);
MyPaint.setColor(Color.parseColor("#8041D9"));
canvas.drawRect(500, 700, 700, 1100, MyPaint);
}
}
}


지난번에 이게 마지막 코드였네요

xml 파일을 안써서 그런지

진짜 편리하네요 


5개월전에 썼던 코드인데

그대로 복사붙여넣기 하고

돌려보니 1cm의

오차도 없이 지난번과

똑같은 결과가 잘 나오네요


canvas.drawLine(startX, startY, stopX, stopY, Paint)


대충보니

이런식으로 써있네요


drawLine(X좌표 시작, Y좌표 시작, X좌표 끝, Y좌표 끝, 페인트)


뭐 간단하게

(0, 0) -> (360, 640)

이 정도로 선을 하나 그려보겠습니다

public class MainActivity extends AppCompatActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
ViewEx viewEx = new ViewEx(this);
setContentView(viewEx);
}

protected class ViewEx extends View
{
public ViewEx(Context context)
{
super(context);
}
public void onDraw(Canvas canvas)
{
canvas.drawColor(Color.BLACK);

Paint MyPaint = new Paint();
MyPaint.setStrokeWidth(5f);
MyPaint.setStyle(Paint.Style.FILL);
MyPaint.setColor(Color.GRAY);
canvas.drawLine(0,0,360,640,MyPaint);
}
}
}


코드는 간단합니다


canvas.drawColor(Color.BLACK);

캔버스(도화지)를 검은색으로 먼저

쫙 칠해놓고


MyPaint라는 펜을 하나 들어서

5f의 두께로 칠해줍니다.

setStyle은 FILL이네요 어짜피

선이라 의미가 없겠지만

색깔은 Gray(회색)으로 선택하였습니다


그리고 좌표를 꼭 집어서 넣어줬습니다

drawLine(0, 0, 360, 640, MyPaint);

복잡하지 않으므로 바로

결과를 보도록 하겠습니다



에뮬레이터로 돌렸는데

휴대폰 둥근부분때문에

이쁘게 못짜르겠네요


어쨋든 결과를 보자면

잘 나온것 같네요


제대로 나왔는지

확인하고 싶으면 아래와 같이

onTouchEvent를 @Override해서

Log로 한번 찍어보면 됩니다

@Override
public boolean onTouchEvent(MotionEvent event)
{
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
Log.d("ITPANGPANG","(x,y)=>"+"("+event.getX()+","+event.getY()+")");
return true;
}
return false;
}



대충 시작과 끝을

쿡쿡 찔러봤는데

비슷하게 나오네요


나중에 여기까지 하게 될지는

모르겠지만 canvas에 그려져있는

paint의 좌표값을

전부 가져오는방법도 있습니다


여러분 onTouch와 친해져야 합니다

canvas에서 뿐만 아니라 개발하다가

막혔을때 onTouch 꼼시로 해결하는 경우가

많이 있습니다~


좀 눈에 잘들어오게 하려면

int x = (int) event.getX();

이렇게 변환해서 하면 알아보기

쉬울겁니다.



canvas.drawPath(path, Paint)


이번에는 drawPath를 보겠습니다

drawPath는 사용방법은 쉽고

효율성은 굉장히 뛰어납니다


사용해보기 위해서

Path, moveTo, lineTo를

사용해보겠습니다


//먼저 Path 객체를 하나 생성하고
Path path = new Path();
//path의 초기위치를 잡아줍니다(moveTo)
path.moveTo(100,100);
//그 다음 x,y의 좌표를 lineTo로 이동시켜주면 됩니다
path.lineTo(100,100);
path.lineTo(100,200);
path.lineTo(200,100);
path.lineTo(200,200);

canvas.drawPath(path,MyPaint);


Path 객체 하나 생성하는것까진

어렵지 않고


moveTo

는 주석으로 달았드시

초기경로를 잡아놓는 부분입니다


그 다음

lineTo를 이용해서

경로를 연장시켜주면 됩니다


path.moveTo(100,100);

path.lineTo(100,100);

path.lineTo(100,200);


여기까지 보면 일단

x(100),y(100) -> x(100),y(200)


y만 100 증가하였으므로

일자로 쭉 내려가게 됩니다


그 다음

path.moveTo(100,100);

path.lineTo(100,100);

path.lineTo(100,200);

path.lineTo(200,100);


여기까지 해주면 X값은

증가하게 되어 오른쪽으로 이동하나

Y값은 200에서 100으로 감소하므로

위쪽으로 이동하게 됩니다


그 다음

path.moveTo(100,100);

path.lineTo(100,100);

path.lineTo(100,200);

path.lineTo(200,100);

path.lineTo(200,200);


마지막으로 다시 Y값을

100 증가시켜서 200으로

설정하면 경로가 다시 아래로

내려오게됩니다.


결과는 이런식으로 나오겠죠?


만약 하나를 더 추가해보면

path.lineTo(300,100);


이런식으로 경로를

자유롭게 잡아줄 수 있습니다


경로를 다 잡고나면

위에처럼 그리기 위해서

canvas.drawPath를 해주면 됩니다.


public class MainActivity extends AppCompatActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
ViewEx viewEx = new ViewEx(this);
setContentView(viewEx);
}

protected class ViewEx extends View
{
public ViewEx(Context context)
{
super(context);
}
public void onDraw(Canvas canvas)
{
canvas.drawColor(Color.BLACK);

Paint MyPaint = new Paint();
MyPaint.setStrokeWidth(5f);
MyPaint.setStyle(Paint.Style.STROKE);
MyPaint.setColor(Color.GRAY);

Path path = new Path();
path.moveTo(100,100);
path.lineTo(100,100);
path.lineTo(100,200);
path.lineTo(200,100);
path.lineTo(200,200);
path.lineTo(300,100);
canvas.drawPath(path,MyPaint);
}
}
}


자 여기서 한가지 더 

path.close라는 것이 있는데

이것을 써주면 마지막 경로에서

시작경로까지 선을 쫙 그려주는

효과가 있습니다


path.lineTo(300,100)

path.close();


이렇게 마지막 경로뒤에 적어주면


이런식의 결과를 얻을 수 있습니다


자 마지막으로

별(???)을 그리면서

마무리 해보도록 하겠습니다.


public class MainActivity extends AppCompatActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
ViewEx viewEx = new ViewEx(this);
setContentView(viewEx);
}

protected class ViewEx extends View
{
public ViewEx(Context context)
{
super(context);
}
public void onDraw(Canvas canvas)
{
canvas.drawColor(Color.BLACK);

Paint MyPaint = new Paint();
MyPaint.setStrokeWidth(5f);
MyPaint.setStyle(Paint.Style.STROKE);
MyPaint.setColor(Color.GRAY);

Path path = new Path();
path.moveTo(450,500);
path.lineTo(450,500);
path.lineTo(400,600);
path.lineTo(300,600);
path.lineTo(400,700);
path.lineTo(350,800);
path.lineTo(450,700);
path.lineTo(550,800);
path.lineTo(500,700);
path.lineTo(600,600);
path.lineTo(500,600);
path.close();
canvas.drawPath(path,MyPaint);
}
}
}



위에는 잘 그렸는데

아래가 ㅠㅠ..


어렵네요