336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

이미지에 관련된 전반적인 사항이니 참고하세요.

 

1. 기본적으로 resource에 저장되어 있는 이미지의 경우 Drawable이라는 오브젝트를 구해와서 화면에 그릴 수가 있습니다.

 

Drawable drawable = getResources().getDrawable(id);

drawable.setBounds(0,0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());  // drawable을 어느 영역에 그릴 것인가?

 

onDraw(canvas canvas) {

           drawable.draw(canvas);

}

 

setBounds에 설정한 값에 따라서 자동으로 이미지가 scaling이 됩니다.

 

원본 이미지 사이즈가 100*50인데 bounds를  (0,0, 200, 100)이라고 설정하면 가로 세로가 2배로 확대되어서 그려지겠죠.

 

2. 임의의 bitmap을 생성하고 bitmap에 원하는 내용그리기

 

다음과 같이 임의의 bitmap을 생성합니다.

Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);

 

Config.ARGB_8888말고 Config.RGB_565 있고 몇가지 있습니다.

 

원하는 걸로 생성하면 되는데 ARGB8888 생성할 경우 투명값을 지정할 수가 있는 반면 RGB_565 생성하시면 불투명한 이미지만 가능합니다.

 

이렇게 만들어진 bitmap에 직접 그림을 그리거나 다른 이미지를 그릴려고 하면 아래와 같이 새로운 canvas를 만들어야 합니다.

 

Canvas canvas = new Canvas();

canvas.setBitmap(bitmap);

 

그러면 향후에 canvas에 그리는 모든 작업은 bitmap에 반영이 됩니다.

 

3. Bitmap Drawable간의 변환

 

안드로이드에서는 bitmap을 직접 다루기보단 대부분 Drawable이라는 wrapping된 형태로 이미지를 처리하기 때문에

 

Bitmap의 경우 종종 Drawable로 변환해야 하는 경우가 있습니다.

 

이를 위해서 BitmapDrawable이라는 클래스가 존재하고 아래와 같은 식으로 사용이 가능합니다.

 

Drawable drawable = (Drawable)(new BitmapDrawable(bitmap));

 

BitmapDrawable은 Drawable로 캐스팅이 가능하죠.

 

4. canvas 처리

 

w*h크기의 drawable 오브젝트가 있을 때 setBounds를 이용하여 임의의 좌표(x,y)에 원형크기대로 출력할려면 아래와 같습니다.

 

obj.setBounds(x,y,x+w,y+h);

obj.draw(canvas);

 

이 방식의 귀찮은 점은 항상 w,h를 지정을 해줘야 하기 때문에 코드도 상당히 길어지고 지저분해보이는 경우가 많습니다.

(getIntrinsicWidth()/Height()로 항상 구하던지 별도의 변수에 값을 유지해야하죠)

 

그래서 위와 같은 방법보다는 아래와 같이 canvas의 좌표이동 변환식을 이용하는게 깔끔합니다.

 

obj.setBounds(0,0,w,h); // 얘는 drawable을 최초로 생성했을 때 한번만 지정하면 됨

 

canvas.save(); // 현재 변환식을 저장

canvas.translate(x,y) // 좌표이동과 관련된 변환식 적용

obj.draw(canvas); // drawable을 그린다.

canvas.restore(); // 원래 변환식으로 복구

 

canvas.translate(x,y) 를 지정할 경우 출력할 이미지를 (x,y)만큼 이동시켜서 그려줍니다. (좌표이동 행렬식이라고 생각하면 됨)

 

블로그 이미지

By훈트

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

 

리소스에서 bitmap을 읽어오고 화면에 출력한 후 touch를 이용해서 drag하는 예제

package com.jjihun.bitmaptest;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class BitmapView extends View {
 Bitmap bitmap;
 int width;
 int height;
 int dx;
 int dy;
 public BitmapView(Context context, AttributeSet attrs) {
  super(context, attrs);

  bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.yuandi);
  // 얘 뒤져보면 byte[] 에서 bitmap생성하는 것도 있심

  width = bitmap.getWidth();
  height = bitmap.getHeight();
 }

 @Override
 protected void onDraw(Canvas canvas) {
  canvas.drawBitmap(
     bitmap, // 출력할 bitmap
     new Rect(0,0,width,height),   // 출력할 bitmap의 지정된 영역을 (sub bitmap)
     new Rect(dx,dy,dx+width,dy+height),  // 이 영역에 출력한다. (화면을 벗어나면 clipping됨)
     null);

  super.onDraw(canvas);
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  
  switch(event.getAction()) {
  case MotionEvent.ACTION_DOWN:
   break;
  case MotionEvent.ACTION_UP:
   break;
  case MotionEvent.ACTION_MOVE:
// 주루룩 drag했을 경우 히스토리가 모두 기록되어서 전달됨
   int length=event.getHistorySize();
   float sx, sy, ex, ey;
   
   if (length != 0) {
    sx = event.getHistoricalX(0);
    sy = event.getHistoricalY(0);
    ex = event.getHistoricalX(length-1);
    ey = event.getHistoricalY(length-1);

    dx += (int)(ex-sx);
    dy += (int)(ey-sy);
   }
   invalidate();
   break;
  }
  
  return true;
 }
}


블로그 이미지

By훈트

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
 
  1. CustomView의 생성과정은 점,선,면의 생성과정과 동일하다
  2. Sample ( Canvas에 출력하기 / Canvas에 궤적추적출력 활용 )
  3. Path는 drawPath, drawTextOnPath와 같이 궤적을 따라 출력하기 위한 객체이다
  4. 벡터정보를 저장하고 궤적을 출력하는등 활용도가 다양하다
  5. 관련 메서드
    1. void addArc(RectF oval, float startAngle, float sweepAngle) : 호의 추가
    2. void addCircle(float x, float y, float radius, Path.Direction dir) : 원의 추가
    3. void addOval(RectF oval, Path.Direction dir)  : 타원의 추가
    4. void addPath(Path src, Matrix matrix) : 행렬이 적용되는 Path의 추가
      1. (Path src)
      2. (Path src, float dx, float dy)
    5. void addRect(RectF rect, Path.Direction dir) : 사각형 추가
      1. (float left, float top, float right, float bottom, Path.Direction dir)
    6. void addRoundRect(RectF rect, float[] radii, Path.Direction dir) :모따진 사각형추가
      1. (RectF rect, float rx, float ry, Path.Direction dir)
    7. void arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)  : 호의 추가
      1. (RectF oval, float startAngle, float sweepAngle)
    8. void close() : 현 궤적의 종료
    9. void computeBounds(RectF bounds, boolean exact) : Path point의 영역산출
    10. void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3) : 베지어 공식의 곡선  
      1. rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3) : 상대좌표사용       
    11. Path.FillType getFillType()  : 현 Path 채우기모드의 반환
    12. void incReserve(int extraPtCount) : Hint to the path to prepare for adding more points.
    13. boolean isEmpty() : 정보가 없는 경우 true를 반환
    14. boolean isInverseFillType()  : 반대변형이 가능한가를 판단
    15. boolean isRect(RectF rect) : 영역의 정보가 사각형인가를 판단
    16. void lineTo(float x, float y) : 마지막 Path에서 선그리기 추가
      1. rLineTo(float dx, float dy)  : 상대좌표 사용
    17. void moveTo(float x, float y) : 좌표이동 추가
      1. rMoveTo(float dx, float dy) : 상대좌표사용
    18. void offset(float dx, float dy) : Offset the path by (dx,dy), returning true on success
      1. (float dx, float dy, Path dst)
    19. void quadTo(float x1, float y1, float x2, float y2)  :
      1. Add a quadratic bezier from the last point, approaching control point (x1,y1), and ending at (x2,y2).
      2. rQuadTo(float dx1, float dy1, float dx2, float dy2) : 상대좌표사용
    20. void reset() : Path정보를 Empty로 만들기
    21. void rewind() : 라인, 커브는 지우고, 내부정보는 다시 사용하는 방법
    22. void set(Path src) : 정보의 수정
    23. void setFillType(Path.FillType ft) : 채우기 지정
    24. void setLastPoint(float dx, float dy) : 최종좌표의 변경
    25. void toggleInverseFillType() : 채우기의 반대모드로 변환하기
    26. void transform(Matrix matrix) : 행렬로 변형하기
      1. transform(Matrix matrix, Path dst)
  6. 사용 순서
    1. public void onDraw(Canvas canvas)에서 사용
      1. Path path = new Path();
      2. Paint paint = new Paint(); // Path출력도 Paint의 정보에 준한다
      3. paint정보 Setting 하기
      4. path정보 만들기
      5. canvas.drawPath( path, paint ) // Path 출력하기
        1. canvas.drawTextOnPath( string, path, 0, 0, paint) // 곡선, 원등에 문자출력하기
블로그 이미지

By훈트

,