///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

방법1(카메라 앱을 이용)

 

MainActivity

...더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package com.example.boostcoursepractice;
 
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
 
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
 
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
 
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
 
import java.io.File;
import java.net.URL;
import java.util.HashMap;
 
public class MainActivity extends AppCompatActivity {
 
    ImageView imageView ;
 
    File file ;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        File sdcard = Environment.getExternalStorageDirectory() ;
        file = new File(sdcard, "capture.jpg");
 
        imageView = (ImageView) findViewById(R.id.imageView);
 
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                capture();
            }
        });
    }
 
    public void capture()
    {
 
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
 
        startActivityForResult(intent, 101);
    }
 
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
 
        if(requestCode == 101 && resultCode == Activity.RESULT_OK) {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 8 ;
            Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
            imageView.setImageBitmap(bitmap);
        }
    }
}
cs

 

activity_main.xml

...더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
 
    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="사진찍기" />
 
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:srcCompat="@android:drawable/sym_def_app_icon" />
</LinearLayout>
 
cs

 

카메라는 이용하는 방법으로는 첫번째로는 카메라 앱을 이용하여 하는 방식이 있다. 아래의 코드 처럼

 

        File sdcard = Environment.getExternalStorageDirectory() ;

        file = new File(sdcard, "capture.jpg");

 

우선 sd카드에 file을 열어주고 없으면 생성된다. 여기서는 capture.jpg라고 파일을 열어주거나 생성되게 함 그리고 나서는

 

 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));

 

        startActivityForResult(intent, 101);

 

위처럼 인텐트를 통하여 카메라 앱을 열어주고 사진을 찍으면 아까 생성한 capture.jpg에 저장되도록 인자로 그 uri를 넘겨준다. 마지막으로

 

   protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

        super.onActivityResult(requestCode, resultCode, data);

 

        if(requestCode == 101 && resultCode == Activity.RESULT_OK) {

            BitmapFactory.Options options = new BitmapFactory.Options();

            options.inSampleSize = 8 ;

            Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options);

            imageView.setImageBitmap(bitmap);

        }

    }

 

위처럼 결과가 오면 사진은 capture.jpg에 저장 됬으므로 그 파일의 절대경로를 인자로 넘겨(옵션은 크기를 줄이기 위하여 넣어줌) 파일을 디코드 시켜 비트맵에 저장하여 다시 이미지 뷰에 저장해준다.

 

 

 

결과화면

 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

방법2(카메라 장치 이용)

 

MainActivity

...더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.example.boostcoursepractice;
 
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
 
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
 
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
 
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
 
import java.io.File;
import java.net.URL;
import java.util.HashMap;
 
public class MainActivity extends AppCompatActivity {
 
    ImageView imageView;
    CameraSurfaceView surfaceView;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        imageView = (ImageView) findViewById(R.id.imageView);
        surfaceView = (CameraSurfaceView) findViewById(R.id.surfaceView);
 
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                capture();
            }
        });
 
 
    }
 
    public void capture() {
        surfaceView.capture(new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] bytes, Camera camera) {
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 8 ;
                Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
 
                imageView.setImageBitmap(bitmap);
 
                camera.startPreview();
            }
        });
    }
}
cs

 

CameraSurfaceView

...더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package com.example.boostcoursepractice;
 
import android.content.Context;
import android.hardware.Camera;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
 
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
 
    SurfaceHolder holder ;
    Camera camera = null ;
 
    public CameraSurfaceView(Context context) {
        super(context);
 
        init(context);
    }
 
    public CameraSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
 
        init(context);
    }
 
    public void init(Context context)
    {
        holder = getHolder();
        holder.addCallback(this);
    }
 
    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
         camera = Camera.open();
 
         try{
             camera.setPreviewDisplay(holder);
         }catch (Exception e){
             e.printStackTrace() ;
         }
    }
 
    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
        camera.startPreview();
    }
 
    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        camera.stopPreview();
        camera.release();
        camera=null;
    }
 
    public boolean capture(Camera.PictureCallback callback)
    {
        if(camera != null)
        {
            camera.takePicture(nullnull, callback);
            return true ;
        }else{
            return false;
        }
    }
}
 
cs

 

activity_main.xml

...더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
 
    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="사진찍기" />
 
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        app:srcCompat="@android:drawable/sym_def_app_icon" />
 
    <com.example.boostcoursepractice.CameraSurfaceView
        android:id="@+id/surfaceView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
</LinearLayout>
 
cs

 

두번째 방법으로는 직접 카메라 장치를 이용하는 방법인데 이 때 SurfaceView를 이용한다. 여기서는 CameraSurfaceView라는 SurfaceView를 상속받은 클래스를 하나 만들어 주고 SurfaceHolder.Callback라는 인터페이스도 implement하였다. 이런 SurfaceView는 껍데기 역할만 해주는 것이고 실질적으로 동작하는 것은 SurfaceHolder가 해준다. 따라서 클래스안에 SurfaceHolder holder, Camera camera 같이 holder와 camera를 만들어 주었다.

 

 public void init(Context context)

    {

        holder = getHolder();

        holder.addCallback(this);

    }

 

일단 처음 뷰가 생성이 되면 init를 해주는데 holder에 홀더를 가져와 할당해주고 holder에 SurfaceHolder.Callback를 implement한 이 클래스를 콜백함수로 등록해 준다. 이 클래스는 SurfaceHolder.Callback에 등록된 surfaceCreatedsurfaceChanged, surfaceDestroyed를 오버라이드 해주었는데 여기서는 카메라를 열고 미리보기를 보여주고 클래스가 없어지면 할당을 해제해주는 함수를 등록해놓았다. 마지막으로 xml파일에 SurfaceView를 만들어 주고 메인액티비티로 돌아가 SurfaceView를 찾아 할당해주고 거기에 아래의 함수

 

public void capture() {

        surfaceView.capture(new Camera.PictureCallback() {

            @Override

            public void onPictureTaken(byte[] bytes, Camera camera) {

                BitmapFactory.Options options = new BitmapFactory.Options();

                options.inSampleSize = 8 ;

                Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);

 

                imageView.setImageBitmap(bitmap);

 

                camera.startPreview();

            }

        });

    }

 

를 호출해주어 그 매개 변수로 Camera.PictureCallback의 onPictureTaken오버라이드하여 생성하여 넘겨준다. 이제 미리보기 화면에서 카메라를 찍으면 byte로 넘어오고 그거 decode하여 bitmap으로 변환하여 이미지 뷰에 설정해주면 된다. 이 과정이 끝나면 미리보기가 끝나므로 다시 camera.startPreview()를 호출해주면 된다.

 

 

결과화면

 

+ Recent posts