Please Enable JavaScript!
Gon[ Enable JavaScript ]

반응형

안드로이드(Android) 비트맵 이미지를 다양한 방법으로 변형하는 예제

 

환경 : Eclipse Mars, Android 4.2.2

 

이번예제는 Bitmap 이미지를 다양하게 다루는 방법에 대해 알아 보겠습니다. 크기를 조절하는 방법, 이미지 회전, 이미지의 외곡에 대한 내용을 확인할수 있는 샘플 입니다.

 

 

우선 이미지 변경을 위한 위젯은 4가지 입니다. 이미지의 크기를 조절하는 Spinner 위젯, 이미지를 회전하기위한 값을 셋팅하는 SeekBar, X 축을 기준으로 이미지를 왜곡시키는 SeekBar, Y 축을 기준으로 이미지를 왜곡시키는 SeekBar 입니다. 4개의 위젯 객체에 대한 이벤트 리스너도 각각 만들어 등록합니다.

 

spinnerScale = (Spinner) findViewById(R.id.scale);
seekbarRotate = (SeekBar) findViewById(R.id.rotate);
seekbarSkewX = (SeekBar) findViewById(R.id.skewx);
seekbarSkewY = (SeekBar) findViewById(R.id.skewy);

spinnerScale.setOnItemSelectedListener(spinScaleOnItemSelectedListener);
seekbarRotate.setOnSeekBarChangeListener(seekbarRotateChangeListener);
seekbarSkewX.setOnSeekBarChangeListener(seekbarSkewXChangeListener);
seekbarSkewY.setOnSeekBarChangeListener(seekbarSkewYChangeListener);

 

다음은 비트맵에 대한 셋팅인데 SDCARD 에서 로딩한 후 넒이값과 높이값을 셋팅합니다. 그리고 화면에 표현을 위해서 ImageView 위젯에 셋팅합니다.

 

private void drawMatrix() {

	Matrix matrix = new Matrix();
	matrix.postScale(curScale, curScale);
	matrix.postRotate(curRotate);
	matrix.postSkew(curSkewX, curSkewY);

	Bitmap resizedBitmap = Bitmap.createBitmap(
			bitmap, 0, 0, bmpWidth, bmpHeight, matrix, true);
	imageView.setImageBitmap(resizedBitmap);

}

 

위에서 만든 drawMatrix() 함수는 각각의 위젯에서 이벤트가 발생해 값들의 변동이 있을 때 호출하는 함수 입니다. Matrix 라는 객체가 화면을 외곡하고, 회전하며, 확대 축소시키는 기능을 합니다. postRotate() 회전이며, postSkew() 외곡함수 입니다. drawMatrix() 함수를 호출해 화면에 비트맵을 변경하기 위해서 각 위젯별로 onProgressChanged() 에 함수들이 들어가 있습니다.

 

public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
	curSkewY = (float) (progress - 100) / 100;
	textSkewY.setText("Skew-Y: " + String.valueOf(curSkewY));
	drawMatrix();
}

public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
	curSkewX = (float) (progress - 100) / 100;
	textSkewX.setText("Skew-X: " + String.valueOf(curSkewX));
	drawMatrix();
}

public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
	curRotate = (float) progress;
	drawMatrix();
}

 

크기를 변경하는 Spinner 위젯은 onItemSelected() 함수가 등록되어 있습니다.

 

public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
	curScale = floatScale[arg2];
	drawMatrix();
}

 

메인 activity 화면구현을 위한 전체 레이아웃 xml 입니다.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:background="#3F0099"
        android:paddingBottom="@dimen/abc_action_bar_icon_vertical_padding"
        android:paddingTop="@dimen/abc_action_bar_icon_vertical_padding"
        android:text="이미지를 자유자재로 다루는 예제 "
        android:textColor="#FFFFFF" />

    <Spinner
        android:id="@+id/scale"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <SeekBar
        android:id="@+id/rotate"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5px"
        android:max="360"
        android:progress="0" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <LinearLayout
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_margin="5px"
            android:layout_weight="1"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/textskewx"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="Skew-X: 0"
                android:textSize="10px" />

            <SeekBar
                android:id="@+id/skewx"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:max="200"
                android:progress="100" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_margin="5px"
            android:layout_weight="1"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/textskewy"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="Skew-Y: 0"
                android:textSize="10px" />

            <SeekBar
                android:id="@+id/skewy"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:max="200"
                android:progress="100" />
        </LinearLayout>
    </LinearLayout>

    <ImageView
        android:id="@+id/imageview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_gravity="center"
        android:scaleType="center" />

</LinearLayout>

 

메인 activity 를 구현하기 위한 전체 소스입니다.


import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;

public class BitmapControlActivity extends Activity {

	private String imageSdCard;

	ImageView imageView;
	Spinner spinnerScale;
	SeekBar seekbarRotate;
	SeekBar seekbarSkewX, seekbarSkewY;
	TextView textSkewX, textSkewY;

	private static final String[] strScale = { 
		"0.2x", "0.5x", "1.0x", "2.0x", "5.0x" };
	private static final Float[] floatScale = { 0.2F, 0.5F, 1F, 2F, 5F };
	private final int defaultSpinnerScaleSelection = 2;

	private ArrayAdapter<String> adapterScale;

	private float curScale = 1F;
	private float curRotate = 0F;
	private float curSkewX = 0F;
	private float curSkewY = 0F;

	Bitmap bitmap;
	int bmpWidth, bmpHeight;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_bitmap_control);
		
		imageSdCard = Environment.getExternalStorageDirectory().toString() + 
				"/Download/view04.png";
		
		imageView = (ImageView) findViewById(R.id.imageview);

		spinnerScale = (Spinner) findViewById(R.id.scale);
		seekbarRotate = (SeekBar) findViewById(R.id.rotate);
		seekbarSkewX = (SeekBar) findViewById(R.id.skewx);
		seekbarSkewY = (SeekBar) findViewById(R.id.skewy);
		
		spinnerScale.setOnItemSelectedListener(spinScaleOnItemSelectedListener);
		seekbarRotate.setOnSeekBarChangeListener(seekbarRotateChangeListener);
		seekbarSkewX.setOnSeekBarChangeListener(seekbarSkewXChangeListener);
		seekbarSkewY.setOnSeekBarChangeListener(seekbarSkewYChangeListener);
		
		textSkewX = (TextView) findViewById(R.id.textskewx);
		textSkewY = (TextView) findViewById(R.id.textskewy);
		
		adapterScale = new ArrayAdapter<String>(this, 
				android.R.layout.simple_spinner_item, strScale);
		adapterScale.setDropDownViewResource(
				android.R.layout.simple_spinner_dropdown_item);
		spinnerScale.setAdapter(adapterScale);
		spinnerScale.setSelection(defaultSpinnerScaleSelection);
		curScale = floatScale[defaultSpinnerScaleSelection];

		bitmap = BitmapFactory.decodeFile(imageSdCard);
		bmpWidth = bitmap.getWidth();
		bmpHeight = bitmap.getHeight();

		drawMatrix();
	}

	private void drawMatrix() {

		Matrix matrix = new Matrix();
		matrix.postScale(curScale, curScale);
		matrix.postRotate(curRotate);
		matrix.postSkew(curSkewX, curSkewY);

		Bitmap resizedBitmap = Bitmap.createBitmap(
				bitmap, 0, 0, bmpWidth, bmpHeight, matrix, true);
		imageView.setImageBitmap(resizedBitmap);

	}

	private SeekBar.OnSeekBarChangeListener seekbarSkewYChangeListener = 
			new SeekBar.OnSeekBarChangeListener() {

		public void onStopTrackingTouch(SeekBar seekBar) {
		}

		public void onStartTrackingTouch(SeekBar seekBar) {
		}

		public void onProgressChanged(SeekBar seekBar, 
int progress, boolean fromUser) {
			curSkewY = (float) (progress - 100) / 100;
			textSkewY.setText("Skew-Y: " + String.valueOf(curSkewY));
			drawMatrix();
		}
	};

	private SeekBar.OnSeekBarChangeListener seekbarSkewXChangeListener = 
			new SeekBar.OnSeekBarChangeListener() {

		public void onProgressChanged(SeekBar seekBar, 
int progress, boolean fromUser) {
			curSkewX = (float) (progress - 100) / 100;
			textSkewX.setText("Skew-X: " + String.valueOf(curSkewX));
			drawMatrix();
		}

		public void onStartTrackingTouch(SeekBar seekBar) {
		}

		public void onStopTrackingTouch(SeekBar seekBar) {
		}
	};

	private SeekBar.OnSeekBarChangeListener seekbarRotateChangeListener = 
			new SeekBar.OnSeekBarChangeListener() {

		public void onProgressChanged(SeekBar seekBar, 
int progress, boolean fromUser) {
			curRotate = (float) progress;
			drawMatrix();
		}

		public void onStartTrackingTouch(SeekBar seekBar) {
		}

		public void onStopTrackingTouch(SeekBar seekBar) {
		}
	};

	private Spinner.OnItemSelectedListener spinScaleOnItemSelectedListener = 
			new Spinner.OnItemSelectedListener() {

		public void onItemSelected(AdapterView<?> arg0, 
View arg1, int arg2, long arg3) {
			curScale = floatScale[arg2];
			drawMatrix();
		}

		public void onNothingSelected(AdapterView<?> arg0) {
			spinnerScale.setSelection(defaultSpinnerScaleSelection);
			curScale = floatScale[defaultSpinnerScaleSelection];
		}
	};
}

 

 

안드로이드(Android) 비트맵 이미지를 다양한 방법으로 변형하는 예제

 

반응형
Posted by 녹두장군

댓글을 달아 주세요