마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

android canvas crop 비율 넣기 계산법

0 추천

android canvas crop 비율 넣기 계산법 명쾌하게 알려주십쇼... 현재는 그냥 자유롭게 잘리고 선이 넘어가고 손볼곳이 너무 많습니다.

 

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;

public class CropImage extends ImageView {
	
	private static final String TAG = "Crop_Image";
	float sx, ex, sy, ey;
	static int DEP = 30; // Crop 경계선의 유효폭(선근처)

	
	ContentResolver mContentResolver;
	ImageCropActivity cnxt;
	Bitmap bitmap;
	float mWidth , bitWidth;
	float mHeight , bitHeight;
	Paint pnt;

	Bitmap hBmp; // 선 가운데의 세로선택 아이콘
	Bitmap wBmp; // 가로
	Bitmap tmp;


	private String outFilePath = FileUtil.getStrFilePath();

	
	public CropImage(Context context, AttributeSet attr) {
		super(context, attr);
		
		
		
		Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
		Point point = new Point();
		display.getSize(point);
		mWidth	= point.x;
		mHeight	= point.y;
		
		
//		sx = mWidth / 5; // 초기s Crop선의 위치 설정
//		ex = mWidth * 4 / 5;
//		sy = mHeight / 5;
//		ey = mHeight * 4 / 5;
		
		
//		sx = mWidth;
//		ex = mWidth;
//		sy = mHeight;
//		ey = mHeight;

		Log.e(TAG, outFilePath);
		cnxt = (ImageCropActivity) context;

		// 비트맵 크기 조절(메모리 문제로 인하여 1/2 크기로)
		BitmapFactory.Options resizeOpts = new Options();
		resizeOpts.inSampleSize = 4;
		try {
			bitmap = BitmapFactory.decodeStream(
					new FileInputStream(outFilePath), null, resizeOpts);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		bitmap = BitmapUtil.resizeBitmap(bitmap, (int)mWidth);
		bitWidth	= bitmap.getWidth();
		bitHeight	= bitmap.getHeight();
//		if(bitHeight > bitWidth){
//			bitmap = BitmapUtil.resizeBitmap(bitmap, (int)mHeight);
//		}else{
//			
//		}
		
		Log.e(TAG, "" + bitHeight * bitWidth);
		
		hBmp = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.shape);
		wBmp = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.shape);

		if(bitWidth > bitHeight){
			sx = mWidth * 0; // 초기s Crop선의 위치 설정
			ex = bitWidth;
			sy = mHeight/7;
			ey = bitHeight + mHeight/7;	
		}else{
			sx = (mWidth - bitWidth)/2; // 초기s Crop선의 위치 설정
			ex = (mWidth - bitWidth)/2 + bitWidth;
			sy = mHeight/20;
			ey = bitHeight + mHeight/20;	
		}
		
		Log.d("크기","mwidth :" + mWidth + " mHeight : " + mHeight + "sx : " + sx + " ex : " + ex + " sy : " + sy + " ey :" + ey);

		
		// 페인트 설정
		pnt = new Paint();
		pnt.setColor(Color.MAGENTA);
		pnt.setStrokeWidth(3);
	}

	public void onDraw(Canvas canvas) {
		// 사각형 라인 그리기
//		canvas.drawBitmap(bitmap, mHeight-bitHeight/2, mWidth-bitWidth/2, null);
		
		if(bitWidth > bitHeight){
			canvas.drawBitmap(bitmap, 0 , mHeight/7 , null);
		}else{
			canvas.drawBitmap(bitmap, ((mWidth - bitWidth)/2) , mHeight/20 , null);
		}
		
		canvas.drawLine(sx, sy, ex, sy, pnt);
//		canvas.drawLine(0, 0, mWidth, 0, pnt);		// 왼쪽 위 점 -> 오른쪽 위 점

		canvas.drawLine(ex, sy, ex, ey, pnt);
//		canvas.drawLine(mWidth, 0, mWidth, mHeight , pnt);			// 오른쪽 위 점 -> 오른쪽 아래 점
		
		canvas.drawLine(sx, sy, sx, ey, pnt);
//		canvas.drawLine(0, 0, 0, mHeight, pnt);			//	시작 점 	-> 왼쪽 아래점
		
		canvas.drawLine(sx, ey, ex, ey, pnt);
//		canvas.drawLine(0, mHeight, mWidth, mHeight, pnt);			//	왼쪽 아래 점 - > 오른쪽 아래점
		
		
		
		// 상하좌우 버튼들
//		canvas.drawBitmap(hBmp, (ex + sx) / 2 - 19, sy - 19, null); // 폭이 38이므로
//		canvas.drawBitmap(hBmp, (ex + sx) / 2 - 19, ey - 19, null);
//		canvas.drawBitmap(wBmp, sx - 19, (ey + sy) / 2 - 19, null);
//		canvas.drawBitmap(wBmp, ex - 19, (ey + sy) / 2 - 19, null);
	}

	// 이벤트 처리, 현재의 그리기 모드에 따른 점의 위치를 조정
	float dx = 0, dy = 0;
	float oldx, oldy;
	boolean bsx, bsy, bex, bey;
	boolean bMove = false;

	public boolean onTouchEvent(MotionEvent e) {
		int x = (int) e.getX();
		int y = (int) e.getY();

		if (e.getAction() == MotionEvent.ACTION_DOWN) {
			oldx = x;
			oldy = y;

			// 눌려진곳이 선 근처인가 확인
			if ((x > sx - DEP) && (x < sx + DEP))
				bsx = true;
			else if ((x > ex - DEP) && (x < ex + DEP))
				bex = true;

			if ((y > sy - DEP) && (y < sy + DEP))
				bsy = true;
			else if ((y > ey - DEP) && (y < ey + DEP))
				bey = true;

			// 어느 하나라도 선택이 되었다면 move에서 값 변경
			if ((bsx || bex || bsy || bey))
				bMove = false;
			else if (((x > sx + DEP) && (x < ex - DEP))
					&& ((y > sy + DEP) && (y < ey - DEP)))
				bMove = true;

			return true;
		}

		if (e.getAction() == MotionEvent.ACTION_MOVE) {
			if (bsx)
				sx = x;
			if (bex)
				ex = x;
			if (bsy)
				sy = y;
			if (bey)
				ey = y;

			// 사각형의 시작 라인보다 끝라인이 크지않게 처리
			if (ex <= sx + DEP) {
				ex = sx + DEP;
				return true;
			}
			if (ey <= sy + DEP) {
				ey = sy + DEP;
				return true;
			}

			// 움직인 거리 구해서 적용
			if (bMove) {
				dx = oldx - x;
				dy = oldy - y;

				sx -= dx;
				ex -= dx;
				sy -= dy;
				ey -= dy;
				
				
				// 화면밖으로 나가지않게 처리
				if (bitWidth>bitHeight? sx <= 0 : sx <= (mWidth - bitWidth)/2)
					sx = bitWidth > bitHeight ? 0 : (mWidth - bitWidth)/2; 
				if (bitWidth>bitHeight ? ex >= mWidth : ex >= (mWidth - bitWidth)/2 + bitWidth)
					ex = bitWidth > bitHeight ? mWidth - 1 : (mWidth - bitWidth)/2 + bitWidth;
				if (bitWidth>bitHeight ?sy <= mHeight/7 : sy <= mHeight/20)
					sy = bitWidth>bitHeight ? mHeight/7 : mHeight/20;
				if (bitWidth>bitHeight ? ey >= bitHeight + mHeight/7 : ey >= bitHeight + mHeight/20)
					ey = bitWidth>bitHeight ? bitHeight + mHeight/7 - 1 : bitHeight + mHeight/20 -1;
			}

			invalidate(); // 움직일때 다시 그려줌
			oldx = x;
			oldy = y;
			return true;
		}

		// ACTION_UP 이면 그리기 종료
		if (e.getAction() == MotionEvent.ACTION_UP) {
			bsx = bex = bsy = bey = bMove = false;
			return true;
		}
		return false;
	}

	// 선택된 사각형의 이미지를 저장
	public void save() {
		if(bitWidth > bitHeight){
			tmp = Bitmap.createBitmap(bitmap, (int) (sx * 0), (int) (sy-mHeight/7),
					(int) (ex - sx), (int) (ey - sy));
		}else{
			tmp = Bitmap.createBitmap(bitmap, (int) (sx - (mWidth - bitWidth)/2), (int) (sy-mHeight/20),
					(int) (ex - sx), (int) (ey - sy));
		}
			
		byte[] byteArray = bitmapToByteArray(tmp);
		File file = new File(outFilePath);

		try {
			FileOutputStream fos = new FileOutputStream(file);
			fos.write(byteArray);
			fos.flush();
			fos.close();
		} catch (Exception e) {
			Toast.makeText(cnxt, "파일 저장 중 에러 발생 : " + e.getMessage(), 0).show();
			return;
		}
	}

	// 이미지를 전송하기위한 테스트 코드
	public byte[] bitmapToByteArray(Bitmap bitmap) {
		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		bitmap.compress(CompressFormat.JPEG, 100, stream);
		byte[] byteArray = stream.toByteArray();
		return byteArray;
	}
}

요런식으로 짜봤는데 혹시 비율 넣는 법좀 부탁드릴수 있을까요 ? 선들 세팅하는 법이요 ... 좌표계산 ㅠㅠ

ParkYoung (300 포인트) 님이 2015년 5월 22일 질문

답변 달기

· 글에 소스 코드 보기 좋게 넣는 법
· 질문에 대해 추가적인 질문이나 의견이 있으면 답변이 아니라 댓글로 달아주시기 바랍니다.
표시할 이름 (옵션):
개인정보: 당신의 이메일은 이 알림을 보내는데만 사용됩니다.
스팸 차단 검사:
스팸 검사를 다시 받지 않으려면 로그인하거나 혹은 가입 하세요.
...