Advertisement
Vassa007

camerafragment

Jun 13th, 2024
584
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 19.16 KB | None | 0 0
  1. package id.precision.agriino.activity.direct_leaves.camera
  2.  
  3. import android.Manifest
  4. import android.content.pm.PackageManager
  5. import android.graphics.Bitmap
  6. import android.graphics.BitmapFactory
  7. import android.graphics.Canvas
  8. import android.graphics.Color
  9. import android.graphics.ColorFilter
  10. import android.graphics.ColorMatrix
  11. import android.graphics.ColorMatrixColorFilter
  12. import android.graphics.ImageFormat
  13. import android.graphics.Matrix
  14. import android.graphics.Paint
  15. import android.hardware.Camera
  16. import android.hardware.usb.UsbDevice
  17. import android.os.Bundle
  18. import android.os.Environment
  19. import android.os.Handler
  20. import android.os.Looper
  21. import android.os.Message
  22. import android.util.Log
  23. import android.view.LayoutInflater
  24. import android.view.MotionEvent
  25. import android.view.Surface
  26. import android.view.View
  27. import android.view.ViewGroup
  28. import android.widget.Toast
  29. import androidx.annotation.ColorInt
  30. import androidx.appcompat.app.AppCompatActivity
  31. import androidx.core.content.ContextCompat
  32. import androidx.navigation.NavController
  33. import androidx.navigation.findNavController
  34. import androidx.navigation.fragment.findNavController
  35. import com.jiangdg.usbcamera.UVCCameraHelper
  36. import com.serenegiant.usb.widget.CameraViewInterface
  37. import id.precision.agriino.R
  38. import id.precision.agriino.base.BaseFragment
  39. import id.precision.agriino.config.util.Loader
  40. import id.precision.agriino.databinding.FragmentCameraBinding
  41. import java.io.ByteArrayOutputStream
  42. import java.io.File
  43. import java.io.FileNotFoundException
  44. import java.io.FileOutputStream
  45. import java.io.IOException
  46. import java.text.SimpleDateFormat
  47. import java.util.Date
  48.  
  49.  
  50. class CameraFragment : BaseFragment<CameraViewModel, FragmentCameraBinding, CameraRepository>(),
  51.     CameraViewInterface.Callback {
  52.  
  53.     private lateinit var mCameraHelper: UVCCameraHelper
  54.     private lateinit var mUVCCameraView: CameraViewInterface
  55.     private lateinit var mCamera: Camera
  56.     private lateinit var jpegCallBack: Camera.PictureCallback
  57.     private val mInstance: CameraFragment? = null
  58.  
  59.     private var isRequest: Boolean = false
  60.     private var isPreview: Boolean = false
  61.     private var isUSB: Boolean = false
  62.  
  63.     private lateinit var currentBitmap: Bitmap
  64.  
  65.     private val navigation: NavController by lazy {
  66.         findNavController()
  67.     }
  68.  
  69.     private val listener= object: UVCCameraHelper.OnMyDevConnectListener {
  70.         override fun onAttachDev(device: UsbDevice?) {
  71.             Log.e(TAG, "onAttachDev: Halo")
  72.             if (mCameraHelper == null || mCameraHelper.usbDeviceCount == 0) {
  73.                 showShortMessage("No USB Camera! Using Back Camera Instead!")
  74.             }
  75.  
  76.             if (!isRequest) {
  77.                 isRequest = true
  78.                 if (mCameraHelper != null) {
  79.                     if (isUSB) {
  80.                         mCameraHelper.requestPermission(0)
  81.                     } else {
  82.                         loadCamera()
  83.                     }
  84.                 }
  85.             }
  86.         }
  87.  
  88.         override fun onDettachDev(device: UsbDevice?) {
  89.             if (isRequest) {
  90.                 isRequest = false
  91.                 mCameraHelper.closeCamera()
  92.                 showShortMessage("USB Camera is dettached!")
  93.             }
  94.         }
  95.  
  96.         override fun onConnectDev(device: UsbDevice?, isConnected: Boolean) {
  97.             if (!isConnected) {
  98.                 showShortMessage("Fail to connect, please check resolution parameters!")
  99.                 isPreview = false
  100.             } else {
  101.                 isPreview = true
  102.                 showShortMessage("Connecting...")
  103.             }
  104.         }
  105.  
  106.         override fun onDisConnectDev(device: UsbDevice?) {
  107.             showShortMessage("Disconnecting...")
  108.         }
  109.     }
  110.  
  111.     private fun showShortMessage(message: String)  {
  112.         Toast.makeText(activity, message, Toast.LENGTH_SHORT).show()
  113.     }
  114.     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
  115.         super.onViewCreated(view, savedInstanceState)
  116.         (activity as AppCompatActivity).setSupportActionBar(binding.topAppBar)
  117.         binding.topAppBar.apply {
  118.             navigationIcon = ContextCompat.getDrawable(context, R.drawable.baseline_arrow_back_24)
  119.             setNavigationOnClickListener {
  120.                 findNavController().popBackStack()
  121.             }
  122.         }
  123.  
  124.  
  125.         with(binding) {
  126.  
  127.             mUVCCameraView = cameraView as CameraViewInterface
  128.             mUVCCameraView.setCallback(this@CameraFragment)
  129.             mCameraHelper = UVCCameraHelper.getInstance()
  130.             mCameraHelper.setDefaultFrameFormat(UVCCameraHelper.FRAME_FORMAT_YUYV)
  131.             mCameraHelper.initUSBMonitor(activity, mUVCCameraView, listener)
  132.  
  133.             frCam.setOnTouchListener { v, event ->
  134.                 if (event.action == MotionEvent.ACTION_DOWN) {
  135.                     val touchX = event.x
  136.                     val touchY = event.y
  137.                     handleTouch(touchX, touchY)
  138.                     focusView.setTouchPosition(touchX, touchY)
  139.                     focusView.visibility = View.VISIBLE
  140.                 }
  141.                 true
  142.             }
  143.  
  144.             fabCapture.setOnClickListener {
  145.                 try {
  146.                     if (mCameraHelper == null || !mCameraHelper.isCameraOpened && !isUSB) {
  147.                         mCamera.parameters = getParameter()
  148.                         mCamera.takePicture(null, null, jpegCallBack)
  149.                     } else {
  150.                         val picPath: String = getFotoPath
  151.                         mCameraHelper.capturePicture(picPath) {
  152.                             // navigation.previousBackStackEntry?.savedStateHandle?.set("path",picPath)
  153.                             //                                navigation.popBackStack()
  154.  
  155.                             Handler(Looper.getMainLooper()).post {
  156.                                 navigation.previousBackStackEntry?.savedStateHandle?.set(
  157.                                     "path",
  158.                                     picPath
  159.                                 )
  160.                                 navigation.popBackStack()
  161.                             }
  162.                         }
  163.  
  164.  
  165.                     }
  166.                 } catch (e: Exception) {
  167.  
  168.                 }
  169.  
  170.  
  171.             }
  172.  
  173.             btnCam.setOnClickListener {
  174.                 Log.e(TAG, "onClick: $isUSB")
  175.                 if (!isUSB) {
  176.                     if (mCameraHelper == null || mCameraHelper.usbDeviceCount == 0) {
  177.                         btnCam.isChecked = false
  178.                         showShortMessage("No USB Camera Detected!")
  179.                     } else {
  180.                         mCameraHelper.requestPermission(0)
  181.                         isUSB = true
  182.                         btnCalibrate.setVisibility(View.VISIBLE)
  183. //                        tvCalibrate.text = "Need Calibration"
  184.                         btnCalibrate.setOnClickListener {
  185.                             try {
  186.                                 if (mCameraHelper == null || !mCameraHelper.isCameraOpened && !isUSB) {
  187.                                     mCamera.parameters = getParameter()
  188.                                     mCamera.takePicture(null, null, jpegCallBack)
  189.                                 } else {
  190.                                     val picPath: String = getFotoPath
  191.  
  192.                                     mCameraHelper.capturePicture(picPath
  193.                                     ) { picPath: String? ->
  194.                                         Handler(Looper.getMainLooper()).post {
  195.                                             val imgFile = File(picPath)
  196.                                             val myBitmap =
  197.                                                 BitmapFactory.decodeFile(imgFile.absolutePath)
  198.  
  199.                                             val (red, green, blue) = extractRGBFromCenter(
  200.                                                 myBitmap
  201.                                             )
  202.                                             Log.d("RGB", "R: $red, G: $green, B: $blue")
  203.  
  204.                                             val index = (0.2126 * red) + (0.7152 * green) + (0.0722)
  205.                                             binding.tvCalibrate.text = "IKI LOH  R=$red, G=$green, B=$blue \n Calibrate Result = $index"
  206.                                         }
  207.                                     }
  208.                                 }
  209.                             } catch (e: Exception) {
  210.                                 e.printStackTrace()
  211.                             }
  212.                         }
  213.                     }
  214.                 } else {
  215.                     tvCalibrate.setVisibility(View.GONE)
  216.                     btnCalibrate.setVisibility(View.GONE)
  217.                     mCameraHelper.closeCamera()
  218.                     loadCamera()
  219.                     isUSB = false
  220.                 }
  221.             }
  222.  
  223.             if (context?.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
  224.                 requestPermissions(arrayOf(Manifest.permission.CAMERA), 100)
  225.             }
  226.  
  227.             jpegCallBack = Camera.PictureCallback { bytes, cameras ->
  228.                 val outStream: FileOutputStream?
  229.                 try {
  230.                     val path: String = getFotoPath
  231.                     outStream = FileOutputStream(path)
  232.                     var bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
  233.                     val matrix = Matrix()
  234.                     matrix.postRotate(90f)
  235.                     bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.width, bmp.height, matrix, true)
  236.  
  237.                     bmp.compress(Bitmap.CompressFormat.JPEG, 100, outStream)
  238.                     outStream.flush()
  239.                     outStream.close()
  240.  
  241.                     // Update the current bitmap
  242.                     currentBitmap = bmp
  243.  
  244.                     // Extract RGB from the center of the bitmap
  245.                     val (red, green, blue) = extractRGBFromCenter(bmp)
  246.                     Log.d("RGB", "R: $red, G: $green, B: $blue")
  247.  
  248.                     // Update UI with RGB values (optional)
  249.                     binding.tvCalibrate.text = "Calibrate: R=$red, G=$green, B=$blue"
  250.  
  251.                     navigation.previousBackStackEntry?.savedStateHandle?.set("path", path)
  252.                     navigation.popBackStack()
  253.  
  254.                 } catch (e: FileNotFoundException) {
  255.                     e.message?.let { showShortMessage(it) }
  256.                 } catch (e: IOException) {
  257.                     e.message?.let { showShortMessage(it) }
  258.                 }
  259.                 refreshCamera()
  260.             }
  261.         }
  262.     }
  263.  
  264.     private fun handleTouch(touchX: Float, touchY: Float) {
  265.         val bitmap = if (::currentBitmap.isInitialized) {
  266.             currentBitmap
  267.         } else {
  268.             return
  269.         }
  270.  
  271.         val focusAreaSize = 100
  272.         val left = (touchX - focusAreaSize / 2).toInt().coerceIn(0, bitmap.width - focusAreaSize)
  273.         val top = (touchY - focusAreaSize / 2).toInt().coerceIn(0, bitmap.height - focusAreaSize)
  274.         val right = (left + focusAreaSize).coerceIn(0, bitmap.width)
  275.         val bottom = (top + focusAreaSize).coerceIn(0, bitmap.height)
  276.  
  277.         val focusAreaBitmap = Bitmap.createBitmap(bitmap, left, top, right - left, bottom - top)
  278.         val (red, green, blue) = extractRGBFromCenter(focusAreaBitmap)
  279.         Log.d("Focus Area RGB", "R: $red, G: $green, B: $blue")
  280.  
  281.         // Update UI with RGB values (optional)
  282.         binding.tvCalibrate.text = "Focus Area RGB: R=$red, G=$green, B=$blue"
  283.     }
  284.  
  285.     private fun extractRGBFromCenter(bitmap: Bitmap): Triple<Int, Int, Int> {
  286.         val centerX = bitmap.width / 2
  287.         val centerY = bitmap.height / 2
  288.         val pixel = bitmap.getPixel(centerX, centerY)
  289.  
  290.         val red = Color.red(pixel)
  291.         val green = Color.green(pixel)
  292.         val blue = Color.blue(pixel)
  293.  
  294.         return Triple(red, green, blue)
  295.     }
  296.  
  297.  
  298.     private fun compressBitmap(bitmap: Bitmap, quality:Int):Bitmap{
  299.         val stream = ByteArrayOutputStream()
  300.         bitmap.compress(Bitmap.CompressFormat.WEBP, quality, stream)
  301.         val byteArray = stream.toByteArray()
  302.         return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
  303.     }
  304.  
  305.     private fun calibrate(bitmap: Bitmap): ByteArray {
  306.  
  307.         val loader = context?.let { Loader(it).setLoader("Calibrating....") }
  308.         loader?.show()
  309.  
  310.         val colorMatrix = ColorMatrix()
  311.         val colorFilter: ColorFilter = ColorMatrixColorFilter(
  312.             colorMatrix
  313.         )
  314.         val argbBitmap = Bitmap.createBitmap(
  315.             bitmap.width, bitmap.height,
  316.             Bitmap.Config.ARGB_8888
  317.         )
  318.         val canvas = Canvas(argbBitmap)
  319.  
  320.         val paint = Paint()
  321.  
  322.         paint.setColorFilter(colorFilter)
  323.         canvas.drawBitmap(bitmap, 0f, 0f, paint)
  324.  
  325.         val width = bitmap.width
  326.         val height = bitmap.height
  327.         val componentsPerPixel = 3
  328.         val totalPixels = width * height
  329.         val totalBytes = totalPixels * componentsPerPixel
  330.  
  331.         val rgbValues = ByteArray(totalBytes)
  332.         @ColorInt val argbPixels = IntArray(totalPixels)
  333.         argbBitmap.getPixels(argbPixels, 0, width, 0, 0, width, height)
  334.         for (i in 0 until totalPixels) {
  335.             @ColorInt val argbPixel = argbPixels[i]
  336.  
  337.             val  red : Int = Color.red(argbPixel)
  338.             val  green : Int = Color.green(argbPixel)
  339.             val  blue : Int = Color.blue(argbPixel)
  340.  
  341.             rgbValues[i * componentsPerPixel + 0] = red.toByte()
  342.             rgbValues[i * componentsPerPixel + 1] = green.toByte()
  343.             rgbValues[i * componentsPerPixel + 2] = blue.toByte()
  344.  
  345.             Log.e("TAG RGB R",red.toByte().toString())
  346.             Log.e("TAG RGB G",red.toByte().toString())
  347.             Log.e("TAG RGB B",red.toByte().toString())
  348.  
  349.             val r_final = 0.2126 * red
  350.             val g_final = 0.7152 * green
  351.             val b_final = 0.0722 * blue
  352.  
  353.             val valuecalibrate = r_final+g_final+b_final
  354.             Log.e("TAG RGB FINAL ",valuecalibrate.toString())
  355.             binding.tvCalibrate.text = "Calibrate : "+valuecalibrate.toString()
  356.  
  357.         }
  358.  
  359.         loader?.dismiss()
  360.  
  361.         return rgbValues
  362.     }
  363.  
  364.     override fun onStart() {
  365.         super.onStart()
  366.         if (mCameraHelper != null) {
  367.             mCameraHelper.registerUSB()
  368.         }
  369.     }
  370.  
  371.     override fun onStop() {
  372.         super.onStop()
  373.         if (mCameraHelper != null) {
  374.             mCameraHelper.unregisterUSB()
  375.         }
  376.     }
  377.  
  378.     @get:Throws(IOException::class)
  379.     private val getFotoPath: String
  380.         private get() {
  381.             var timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
  382.             var imageFileName = "Agrilcam_" + timeStamp + "_"
  383.             //        String imageFileName = ;
  384.             val storageDir = context?.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
  385.             val image = File.createTempFile(imageFileName, ".jpg", storageDir)
  386.             return image.absolutePath
  387.         }
  388.  
  389.  
  390.     private fun getParameter(): Camera.Parameters {
  391.         val params = mCamera.parameters
  392.         var bestSize: Camera.Size? = null
  393.  
  394.         val sizeList = mCamera.parameters.supportedPreviewSizes
  395.         bestSize = sizeList[0]
  396.         for (i in 1 until sizeList.size) {
  397.             if (sizeList[i].width * sizeList[i].height > bestSize!!.width * bestSize.height) {
  398.                 bestSize = sizeList[i]
  399.             }
  400.         }
  401.  
  402.         val supportedPreviewFormats: List<Int> = params.supportedPreviewFormats
  403.         val supportedPreviewFormatsIterator = supportedPreviewFormats.iterator()
  404.         while (supportedPreviewFormatsIterator.hasNext()) {
  405.             val previewFormat = supportedPreviewFormatsIterator.next()
  406.             if (previewFormat == ImageFormat.YV12) {
  407.                 params.previewFormat = previewFormat
  408.             }
  409.         }
  410.         //params.setPreviewSize(bestSize.width, bestSize.height);
  411.         //params.setPictureSize(bestSize.width, bestSize.height);
  412.         //params.setPreviewSize(bestSize.width, bestSize.height);
  413.         //params.setPictureSize(bestSize.width, bestSize.height);
  414.         params.setPreviewSize(640, 480)
  415.         params.setPictureSize(640, 480)
  416.         return  params
  417.     }
  418.  
  419.     private fun loadCamera() = try {
  420.         mCamera = Camera.open()
  421.         mCamera.parameters = getParameter()
  422.         mCamera.setDisplayOrientation(90)
  423.         mCamera.setPreviewTexture(mUVCCameraView.surfaceTexture)
  424.         mCamera.startPreview()
  425.     } catch (e: Exception) {
  426.         showShortMessage("Camera:" + e.message)
  427.     }
  428.  
  429.     private fun refreshCamera() {
  430.         try {
  431.             mCamera.stopPreview()
  432.         } catch (e: Exception) {
  433.             e.message?.let { showShortMessage(it) }
  434.         }
  435.  
  436.         try {
  437.             mCamera = Camera.open()
  438.             mCamera.parameters = getParameter()
  439.             mCamera.setDisplayOrientation(90)
  440.             mCamera.setPreviewTexture(mUVCCameraView.surfaceTexture)
  441.             mCamera.startPreview()
  442.         } catch (e: Exception) {
  443.             e.message?.let { showShortMessage(it) }
  444.         }
  445.     }
  446.  
  447.     override fun onDestroy() {
  448.         super.onDestroy()
  449.         if (mCameraHelper != null) {
  450.             mCameraHelper.release()
  451.         }
  452.     }
  453.     override fun onSurfaceCreated(view: CameraViewInterface?, surface: Surface?) {
  454.         if (!isPreview && mCameraHelper.isCameraOpened()) {
  455.             mCameraHelper.startPreview(mUVCCameraView);
  456.             isPreview = true;
  457.         }
  458.     }
  459.  
  460.     override fun onSurfaceChanged(
  461.         view: CameraViewInterface?,
  462.         surface: Surface?,
  463.         width: Int,
  464.         height: Int
  465.     ) {
  466.  
  467.     }
  468.  
  469.     override fun onSurfaceDestroy(view: CameraViewInterface?, surface: Surface?) {
  470.         if (isPreview && mCameraHelper.isCameraOpened()) {
  471.             mCameraHelper.stopPreview();
  472.             isPreview = false;
  473.         }
  474.     }
  475.  
  476.     private val mDebugHandler: Handler = object : Handler(
  477.     ) {
  478.         override fun handleMessage(msg: Message) {
  479.             var text = "mDebugHandler="
  480.             when (msg.what) {
  481.                 MESSAGE_SHOW_TEXT -> if (msg.obj != null) {
  482.                     text += msg.obj.toString()
  483.                 }
  484.  
  485.                 MESSAGE_FRAME_COUNT -> sendEmptyMessageDelayed(MESSAGE_FRAME_COUNT, 1000)
  486.                 else -> return
  487.             }
  488. //            mDebugInfo.setText(text)
  489.             Log.e(TAG, "handleMessage: $text", )
  490.         }
  491.     }
  492.  
  493.  
  494.     fun showDebugText(text: String?) {
  495.         if (mInstance!!.mDebugHandler != null) {
  496.             mInstance.mDebugHandler.sendMessage(
  497.                 mInstance.mDebugHandler.obtainMessage(
  498.                     MESSAGE_SHOW_TEXT,
  499.                     text
  500.                 )
  501.             )
  502.         }
  503.     }
  504.  
  505.  
  506.  
  507.     companion object {
  508.         private val TAG = "LOH HEH!!"
  509.         private const val MESSAGE_SHOW_TEXT = 0
  510.         private const val MESSAGE_FRAME_COUNT = 1
  511.     }
  512.  
  513.     override fun getViewModel() = CameraViewModel::class.java
  514.  
  515.     override fun getFragmentBinding(
  516.         inflater: LayoutInflater,
  517.         container: ViewGroup?
  518.     )= FragmentCameraBinding.inflate(inflater, container, false)
  519.  
  520.     override fun getFragmentRepository() = CameraRepository()
  521. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement