Android Study

Camera 사용

85chong 2021. 12. 28. 14:51
728x90
반응형
SMALL
package kr.co.newlinkcorp.cashierest.camera

import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.os.Bundle
import android.util.Base64
import android.util.Log
import android.util.Rational
import android.util.Size
import androidx.camera.core.*
import androidx.camera.core.impl.ImageAnalysisConfig
import androidx.camera.core.impl.PreviewConfig
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import androidx.lifecycle.LifecycleOwner
import kr.co.newlinkcorp.cashierest.base.BaseActivity
import kr.co.newlinkcorp.cashierest.databinding.ActivityCameraReBinding
import java.io.*
import java.lang.Exception
import java.nio.ByteBuffer
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors


class CameraActivityRe:BaseActivity() {

    private lateinit var viewBinding: ActivityCameraReBinding
    private lateinit var mCameraExecutor:ExecutorService
    private var mImageCapture:ImageCapture? = null

    private var mImageAnalysis:ImageAnalysis? = null

    private var isCaptured = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewBinding = ActivityCameraReBinding.inflate(layoutInflater)
        setContentView(viewBinding.root)
        startCamera()
        viewBinding.btnClose.setOnClickListener {
            finish()
        }
        viewBinding.buttonCapture.setOnClickListener {
            captureCameraPreview()
        }
        mCameraExecutor = Executors.newSingleThreadExecutor()
    }

    override fun onBackPressed() {
        super.onBackPressed()
        finish()
    }

    @SuppressLint("UnsafeExperimentalUsageError")
    fun startCamera(){
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        cameraProviderFuture.addListener(Runnable {

            val cameraSelector = CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                .build()

            //uses
            val preview = Preview.Builder().build()
            preview.setSurfaceProvider(viewBinding.previewView.surfaceProvider)

            //uses
            mImageCapture = ImageCapture.Builder()
                .setTargetResolution(Size(720,1600))
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                .build()

            val useCaseGroup = UseCaseGroup.Builder()
                .addUseCase(preview)
                .addUseCase(mImageCapture!!)
                .build()

            val cameraProvider = cameraProviderFuture.get()
            cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, useCaseGroup)


        }, ContextCompat.getMainExecutor(this))
    }

    fun captureCameraPreview(){
        val imageCapture = mImageCapture?:return
        imageCapture.takePicture(mCameraExecutor,object :ImageCapture.OnImageCapturedCallback(){
            override fun onCaptureSuccess(image: ImageProxy) {
                val bitmap:Bitmap = imageProxyToBitmap(image)
                var rotateBitmap = bitmap.customRotate(90f)

                Log.d("181818","rotateBitmap.width : ${rotateBitmap.width}")
                Log.d("181818","rotateBitmap.height : ${rotateBitmap.height}")

                val byteArr = bitmapCompressToByteArray(rotateBitmap)
                val final_result = byteArrayToBase64String(byteArr)

                //TEST TEST
                writeTxTfile(final_result)

                super.onCaptureSuccess(image)
            }
            override fun onError(exception: ImageCaptureException) {
                super.onError(exception)
            }
        })
    }

    fun bitmapCompressToByteArray(bitmap: Bitmap):ByteArray{
        //0 ~ 100
        var quallity_level = 10
        var stream = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.PNG,quallity_level,stream)
        var bitmapData = stream.toByteArray()
        return bitmapData
    }

    private fun imageProxyToBitmap(image:ImageProxy):Bitmap{
        val planProxy = image.planes[0]
        val buffer:ByteBuffer = planProxy.buffer
        val bytes = ByteArray(buffer.remaining())
        buffer.get(bytes)
        return BitmapFactory.decodeByteArray(bytes,0,bytes.size)
    }

    //Text 파일 입력후 파일 생성
    fun writeTxTfile(strValue: String){
        var filename = "yckBase64StringValue.txt"
        var file = File(getExternalFilesDir(null), filename)
        try {
            var fos = FileOutputStream(file)
            var writer = BufferedWriter(OutputStreamWriter(fos))
            writer.write(strValue)
            writer.flush()
            writer.close()
        }catch (e: Exception){
            Log.e("writeTxTfile", "e : ${e.message}")
            return
        }
        Log.e("writeTxTfile", "complete")
    }

    //Bitmap rotate
    fun Bitmap.customRotate(degrees:Float) = Bitmap.createBitmap(this,0,0,width,height, Matrix().apply{
        postRotate(degrees) },true)


    //byteArr -> Base64String
    fun byteArrayToBase64String(byteArray: ByteArray):String{
        //ByteArray -> Base64String 변환
        val byteArrString_result = Base64.encodeToString(byteArray, Base64.DEFAULT)
        //앞뒤 공백 제거
        var trim_from_get3000Data = byteArrString_result.trim()
        //개행문자 제거
        var final_Result = trim_from_get3000Data.replace(
            "\\r\\n|\\r|\\n|\\n\\r".toRegex(),
            ""
        )
        return final_Result
    }

    fun getOptimalSize(sizes:List<Size>,w:Int,h:Int){

    }

    override fun onDestroy() {
        super.onDestroy()
        mCameraExecutor.shutdown()
    }

}//class end