본문 바로가기

Android Studio를 활용한 안드로이드 프로그래밍

8장. 파일 처리 / 9장. 그래픽과 이미지

파일 처리

내장 메모리

파일 저장 위치

/data/data/패키지명/files/

 

내장 메모리에서의 파일 처리 절차

 

예제

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    Button btnWrite = (Button)findViewById(R.id.btnWrite);
    Button btnRead = (Button)findViewById(R.id.btnRead);
    
    btnWrite.setOnClickListener(new View.OnClickListener() {
    	public void onClick(View v) {
        	try{
            	FileOutputStream outFs = openFileOutput("file.txt", Context.MODE_PRIVATE);
                String str = "test";
                outFs.write(str.getBytes());
                outFs.close();
            } catch (IOException e) { }
            
        }
    });
    
    btnRead.setOnClickListener(new View.OnClickListener() {
    	public void onClick(View v) {
        	try{
            	FileInputStream inFs = openFileInput("file.txt");
                byte[] txt = new byte[30];
                inFs.read(txt);
                String str = new String(txt);
                Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
                inFs.close();
            } catch (IOException e) { }
        }
    });
}

 

raw 폴더 파일 처리

파일의 위치

/res/raw/

 

특징

/res/raw 는 프로젝트에 포함된 폴더이므로 읽기 전용이다.

때문에 파일을 쓰기 위해서는 내장 메모리나 SD 카드를 사용해야 한다.

 

예제

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    Button btnRead = (Button)findViewById(R.id.btnRead);
    final EditText edtRaw = (Button)findViewById(R.id.edtRaw);
    
    btnRead.setOnClickListener(new View.OnClickListener() {
    	public void onClick(View v) {
        	try{
            	InputStream InputS = getResources().openRawResource(R.raw.raw_test);
                byte[] txt = new byte[InputS.available()];
                inputS.read(txt);
                edtRaw.setText(new String(txt));
                inputS.close();
            } catch (IOException e) { }
        }
    });
}

 

SD카드에서 파일 읽기

SD카드의 기본적인 경로

/sdcard/
/storage/emulated/0/

 

SD 카드에 접근하기 위한 퍼미션 지정

  1. AndroidManifest.xml
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <application
    	android:requestLegacyExternalStorage="true"
        ...​
  2. Java 코드
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    	setContentView(R.layout.activity_main);
        
    	ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, MODE_PRIVATE);
    	...
    }

 

SD 카드에서 파일 읽기

폴더 경로가 다른 것만 제외하면 내장 메모리와 코드가 동일하다.

(근데 예제 실습시 잘 되지 않음..)

 

 

SD 카드에 폴더 및 파일 생성

Environment 클래스의 정적 메소드를 통해 SD 카드의 절대 경로를 구한 뒤 폴더 생성 / 삭제

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
    
	ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, MODE_PRIVATE);
	
    Button btnMkdir, btnRmdir;
    btnMkdir = (Button)findViewById(R.id.btnMkdir);
    btnRmdir = (Button)findViewById(R.id.btnRmdir);
    final String strSDpath = Enviroment.getExternalStorageDirectory().getAbsolutePath();
    final File myDir = new File(strSDpath + "/mydir");
    
    btnMkdir.setOnClickListener(new View.OnClickListener) {
    	public void onClick(View v) {
        	myDir.mkdir();
        }
    };
    
    btnRmdir.setOnClickListener(new View.OnClickListener) {
    	public void onClick(View v) {
        	myDir.delete();
        }
    };
}

 

특정 폴더의 하위 폴더 및 파일 목록

File.listFiles() 메소드를 통해 File[] 배열 형태로 사용 가능

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
    
    Button btnFilelist;
    final EditText edtFilelist;
    btnFilelist = (Button)findViewById(R.id.btnFilelist);
    edtFilelist = (EditText)findViewById(R.id.edtFilelist);
    
    btnFilelist.setOnClickListener(new View.OnClickListener) {
    	public void onClick(View v) {
        	String sysDir = Enviroment.getRootDirectory().getAbsolutePath();
            File[] sysFiles = (new File(sysDir).listFiles());
            
            String strFname;
            for(int i = 0; i < sysFiles.length; i++) {
            	if(sysFiles[i].isDirectory() == true)
                	strFname = "<폴더> " + sysFiles[i].toString();
                else
                	strFname = "<파일> " + sysFiles[i].toString();
                    
                edtFilelist.setText(edtFilelist.getText() + "\n" + strFname);
            }
        }
    };
}

 

 

 

 

 

 

그래픽과 이미지

그래픽

캔버스와 페인트

화면에 도형을 그리기 위해 사용하는 클래스는 'Canvas', 'Paint' 이다.

 

캔버스는 도화지, 페인트는 붓과 같은 개념으로 생각할 수 있다.

 

그래픽 표현시 View 클래스를 재정의하는 형태로 사용

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
	setContentView(new 재정의한 클래스 이름(this));
}

private static class 재정의한 클래스 이름 extends View {
	public 재정의한 클래스 이름(Context context) {
    	super(context);
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
    	super.onDraw(canvas);
        // 화면에 그려질 내용을 이곳에 코딩
    }
}

 

예제

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
	setContentView(new MyGraphicView(this));
}

private static class MyGraphicView extends View {
	public MyGraphicView(Context context) {
    	super(context);
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
    	super.onDraw(canvas);
        
        //선 그리기
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.BLUE);
        paint.setStrokeWidth(5);
        
        // 사각형 그리기
        paint.setStyle(Paint.Style.FILL); // STROKE
        Rect rect1 = new Rect(10, 50, 10+100, 50+100);
        canvas.drawRect(rect1, paint);
        
        // 원 그리기
        canvas.drawCircle(60, 220, 50, paint); // (중심x, 중심y, 반지름, Paint)
    }
}

 

 

이미지

비트맵의 기본

Bitmap 클래스는 캔버스에 이미지 파일을 보여주는데 사용된다.

 

리소스 이미지는 BitmapFactory.decodeResource() 메소드를 통해 접근한다.

SD 카드의 이미지는 BitmapFactory.decodeFile() 메소드를 이용하여 접근한다.

 

이미지 화면 출력은 공통적으로 canvas.drawBitmap() 메소드를 사용한다.

 

비트맵 리소스 해제는 picture.recucle() 메소드를 사용한다.

 

  1. /res/drawable 폴더의 이미지 파일을 보여주는 onDraw() 메소드
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    	
        Bitmap picture = BitmapFactory.decodeResource(getResources(), R.drawable.그림id);
        canvas.drawBitmap(picture, 시작x, 시작y, null);
        picture.recycle();
    }


  2. SD 카드의 이미지 파일을 보여주는 onDraw() 메소드
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    	
        Bitmap picture = BitmapFactory.decodeFile("파일경로 및 파일");
        canvas.drawBitmap(picture, 시작x, 시작y, null);
        picture.recycle();
    }

 

이미지의 기하학적 변환

이동 : translate()

회전 : rotate()

확대/축소 : scale()

기울이기: skew()

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
	Bitmap picture = BitmapFactory.decodeResource(getResources(), R.drawable.small);
    
    int cenX = this.getWidth() / 2;
    int cenY = this.getHeight() / 2;
    int picX = (this.getWidth() - picture.getWidth()) / 2;
    int picY = (this.getHeight() - picture.getHeight()) / 2;
    
    canvas.rotate(45, cenX, cenY); // 캔버스 45도 회전. cenX, cenY는 회전시키는 기준
    canvas.drawBitmap(picture, picX, picY, null);
    
    canvas.translate(-150, 200); // 캔버스 이동
    canvas.drawBitmap(picture, picX, picY, null);
    
    canvas.scale(2, 2, cenX, cenY); // 캔버스 2배 확대
    canvas.drawBitmap(picture, picX, picY, null);
    
    canvas.skew(0.3f, 0.3f); // 캔버스 0.3f 만큼 기울이기
    canvas.drawBitmap(picture, picX, picY, null);
    
    picture.recucle();
}

 

이미지 활용

블러링

이미지를 뿌옇게 만든다.

반지름이 클수록 이미지의 가장자리가 크게 블러링 된다.

스타일은 NORMAL, INNER, OUTER, SOLID

BlurMaskFilter(반지름, 스타일);

 

엠보싱

이미지가 볼록하게 튀어나와 보이는 효과를 낸다

EmbossMaskFilter(빛의 xyz 방향 일차전 배열, 빛의 밝기, 반사 계수, 블러링 크기);

 

컬러매트릭스

색상이나 밝기를 조절하기 위해 ColorMatrix 클래스와 ColorMatrixColor Filter 클래스를 사용한다.

Paint paint = new Paint();
float[] array = { 4 x 5 배열 };
ColorMatrix cm = new ColorMatrix(array);
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(...);

 

ColorMatrix 배열은 4x5 크기로 각 위치 값은 다음과 같다.

Red(1)		0			0			0			Brightness(0)
0		Green(1)		0			0			Brightness(0)
0		0			Blue(1)			0			Brightness(0)
0		0			0			Alpha(1)		0

 

Red, Green, Blue, Alpha 값은 기본적으로 1이며, 이 값을 몇 배롤 올리면 색상의 대비(contrast)가 커진다.

Brightness에 양수를 입력하면 밝아지고, 음수를 입력하면 어두워진다.