Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
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
Archives
Today
Total
관리 메뉴

쨍쨍

#8. AI Smart Home_CctvActivity 본문

프로그래밍 코드/Android Studio

#8. AI Smart Home_CctvActivity

이선선 2024. 12. 17. 19:46

[ Cctv 화면 ]

 

 

 

 

 

[ activity_cctv.xml ]

 

 

<?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:id="@+id/main"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".CctvActivity">

    <ImageView
        android:layout_width="360dp"
        android:layout_height="80dp"
        android:layout_gravity="center"
        android:layout_marginTop="16dp"
        android:background="@drawable/cctv2"
        android:contentDescription="@string/StringValue"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1">

        <ImageView
            android:id="@+id/iv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </LinearLayout>



</LinearLayout>

 

 

 

[ CctvActivity.java ]

 

 

import android.Manifest;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.widget.ImageView;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;

import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;

import com.gun0912.tedpermission.PermissionListener;
import com.gun0912.tedpermission.TedPermission;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class CctvActivity extends AppCompatActivity {

    private static final int REQUEST_IMAGE_CAPTURE = 672;
    private String imageFilePath;
    private Uri photoUri;

    private ActivityResultLauncher<Intent> startActivityResult = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            new ActivityResultCallback<ActivityResult>() {
                @Override
                public void onActivityResult(ActivityResult result) {
                    if (result.getResultCode() == RESULT_OK) {
                        Bitmap bitmap = BitmapFactory.decodeFile(imageFilePath);
                        ExifInterface exif = null;
                        try {
                            exif = new ExifInterface(imageFilePath);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        int exifOrientation;
                        int exifDegree;

                        if (exif != null) {
                            exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
                            exifDegree = exifOrientationToDegrees(exifOrientation);
                        } else {
                            exifDegree = 0;
                        }

                        ((ImageView) findViewById(R.id.iv)).setImageBitmap(rotate(bitmap, exifDegree));
                    }
                }
            });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PermissionListener permissionListener = new PermissionListener() {
            @Override
            public void onPermissionGranted() {
                // 권한이 허용되었을 때의 동작
                startCamera(); // 권한이 허용된 후 카메라 실행
            }

            @Override
            public void onPermissionDenied(List<String> deniedPermissions) {
                // 권한이 거부되었을 때의 동작
            }
        };

        TedPermission.with(getApplicationContext())
                .setPermissionListener(permissionListener)
                .setRationaleMessage("카메라 권한이 필요합니다.")
                .setDeniedMessage("거부하셨습니다.")
                .setPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA)
                .check();
    }

    private void startCamera() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if( intent.resolveActivity(getPackageManager()) != null) {
            File photoFile = null;
            try {
                photoFile = createImageFile();  // 이미지 파일 생성
            } catch (IOException e) {
                e.printStackTrace();
            }
            if(photoFile != null) {
                // 여기서 authority 값을 정확하게 지정
                photoUri = FileProvider.getUriForFile(getApplicationContext(), "com.example.smarthome_v3.provider", photoFile);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);  // 카메라 앱에 파일 URI 전달
                startActivityResult.launch(intent);  // 카메라 앱 실행
            }
        }
    }

    private File createImageFile() throws IOException {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "TEST_" + timeStamp + "_";
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,
                ".jpg",
                storageDir
        );
        imageFilePath = image.getAbsolutePath();
        return image;
    }

    private int exifOrientationToDegrees(int exifOrientation) {
        if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
            return 90;
        } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
            return 180;
        } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
            return 270;
        }
        return 0;
    }

    private Bitmap rotate(Bitmap bitmap, int exifDegree) {
        Matrix matrix = new Matrix();
        matrix.postRotate(exifDegree);
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    }
}

 

[ 기능 구현하면서 느낀점 ]

 

  졸업 작품 중에서 가장 어렵다고 생각했던 부분 중 하나는 Cctv 연결이다. 카메라로 Cctv 기능을 구현하기까지 여러 과정을 거쳤다. 처음에는 아두이노 카메라 렌즈를 사용해보았지만, 카메라 미리보기(즉, Cctv처럼 실시간으로 볼 수 있는 기능)이 되지 않았다. 그 해결방안으로는 라즈베리파이 카메라를 사용해보았다. 라즈베리파이 카메라는 os를 사용해서 라즈베리파이를 키고 카메라 미리보기 기능까지는 구현했지만, 작성하고 있던 [ Ai Smart Home ] 코드와 연결이 되지 않았다. 마지막으로 시도한 방법은 웹캠을 이용한 Cctv 기능 구현이다.

  웹캠 자체는 PC에 USB를 연결하면 따로 설치하거나 설정할 필요 없이 카메라 미리보기가 되기 때문에 바로 Cctv기능을 구현할 수 있었다. 코드와 연결하는 것 또한 어렵지 않았다. 하지만 단점은 웹캠은 무조건 PC에 연결해야하기 때문에 설계한 부분과 같은 기능을 하지만 방식 자체는 의도한 바와 달랐다. 현재 흔하게 사용하는 Cctv는 PC와 연결하지 않지만 우리가 사용하는 (웹캠을 사용한) Cctv는 무조건 PC에 연결해야지만 동작하기 때문이다.

  그 부분이 아쉽지만, Cctv 기능을 구현하는 과정에서 주어진 시간 안에 어떻게든 기능을 구현하기 위해 여러가지 방식을 찾는 경험을 할 수 있었다.