Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package id.precision.agriino.activity.direct_leaves.camera
- import android.Manifest
- import android.content.pm.PackageManager
- import android.graphics.Bitmap
- import android.graphics.BitmapFactory
- import android.graphics.Canvas
- import android.graphics.Color
- import android.graphics.ColorFilter
- import android.graphics.ColorMatrix
- import android.graphics.ColorMatrixColorFilter
- import android.graphics.ImageFormat
- import android.graphics.Matrix
- import android.graphics.Paint
- import android.hardware.Camera
- import android.hardware.usb.UsbDevice
- import android.os.Bundle
- import android.os.Environment
- import android.os.Handler
- import android.os.Looper
- import android.os.Message
- import android.util.Log
- import android.view.LayoutInflater
- import android.view.MotionEvent
- import android.view.Surface
- import android.view.View
- import android.view.ViewGroup
- import android.widget.Toast
- import androidx.annotation.ColorInt
- import androidx.appcompat.app.AppCompatActivity
- import androidx.core.content.ContextCompat
- import androidx.navigation.NavController
- import androidx.navigation.findNavController
- import androidx.navigation.fragment.findNavController
- import com.jiangdg.usbcamera.UVCCameraHelper
- import com.serenegiant.usb.widget.CameraViewInterface
- import id.precision.agriino.R
- import id.precision.agriino.base.BaseFragment
- import id.precision.agriino.config.util.Loader
- import id.precision.agriino.databinding.FragmentCameraBinding
- import java.io.ByteArrayOutputStream
- import java.io.File
- import java.io.FileNotFoundException
- import java.io.FileOutputStream
- import java.io.IOException
- import java.text.SimpleDateFormat
- import java.util.Date
- class CameraFragment : BaseFragment<CameraViewModel, FragmentCameraBinding, CameraRepository>(),
- CameraViewInterface.Callback {
- private lateinit var mCameraHelper: UVCCameraHelper
- private lateinit var mUVCCameraView: CameraViewInterface
- private lateinit var mCamera: Camera
- private lateinit var jpegCallBack: Camera.PictureCallback
- private val mInstance: CameraFragment? = null
- private var isRequest: Boolean = false
- private var isPreview: Boolean = false
- private var isUSB: Boolean = false
- private lateinit var currentBitmap: Bitmap
- private val navigation: NavController by lazy {
- findNavController()
- }
- private val listener= object: UVCCameraHelper.OnMyDevConnectListener {
- override fun onAttachDev(device: UsbDevice?) {
- Log.e(TAG, "onAttachDev: Halo")
- if (mCameraHelper == null || mCameraHelper.usbDeviceCount == 0) {
- showShortMessage("No USB Camera! Using Back Camera Instead!")
- }
- if (!isRequest) {
- isRequest = true
- if (mCameraHelper != null) {
- if (isUSB) {
- mCameraHelper.requestPermission(0)
- } else {
- loadCamera()
- }
- }
- }
- }
- override fun onDettachDev(device: UsbDevice?) {
- if (isRequest) {
- isRequest = false
- mCameraHelper.closeCamera()
- showShortMessage("USB Camera is dettached!")
- }
- }
- override fun onConnectDev(device: UsbDevice?, isConnected: Boolean) {
- if (!isConnected) {
- showShortMessage("Fail to connect, please check resolution parameters!")
- isPreview = false
- } else {
- isPreview = true
- showShortMessage("Connecting...")
- }
- }
- override fun onDisConnectDev(device: UsbDevice?) {
- showShortMessage("Disconnecting...")
- }
- }
- private fun showShortMessage(message: String) {
- Toast.makeText(activity, message, Toast.LENGTH_SHORT).show()
- }
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- (activity as AppCompatActivity).setSupportActionBar(binding.topAppBar)
- binding.topAppBar.apply {
- navigationIcon = ContextCompat.getDrawable(context, R.drawable.baseline_arrow_back_24)
- setNavigationOnClickListener {
- findNavController().popBackStack()
- }
- }
- with(binding) {
- mUVCCameraView = cameraView as CameraViewInterface
- mUVCCameraView.setCallback(this@CameraFragment)
- mCameraHelper = UVCCameraHelper.getInstance()
- mCameraHelper.setDefaultFrameFormat(UVCCameraHelper.FRAME_FORMAT_YUYV)
- mCameraHelper.initUSBMonitor(activity, mUVCCameraView, listener)
- frCam.setOnTouchListener { v, event ->
- if (event.action == MotionEvent.ACTION_DOWN) {
- val touchX = event.x
- val touchY = event.y
- handleTouch(touchX, touchY)
- focusView.setTouchPosition(touchX, touchY)
- focusView.visibility = View.VISIBLE
- }
- true
- }
- fabCapture.setOnClickListener {
- try {
- if (mCameraHelper == null || !mCameraHelper.isCameraOpened && !isUSB) {
- mCamera.parameters = getParameter()
- mCamera.takePicture(null, null, jpegCallBack)
- } else {
- val picPath: String = getFotoPath
- mCameraHelper.capturePicture(picPath) {
- // navigation.previousBackStackEntry?.savedStateHandle?.set("path",picPath)
- // navigation.popBackStack()
- Handler(Looper.getMainLooper()).post {
- navigation.previousBackStackEntry?.savedStateHandle?.set(
- "path",
- picPath
- )
- navigation.popBackStack()
- }
- }
- }
- } catch (e: Exception) {
- }
- }
- btnCam.setOnClickListener {
- Log.e(TAG, "onClick: $isUSB")
- if (!isUSB) {
- if (mCameraHelper == null || mCameraHelper.usbDeviceCount == 0) {
- btnCam.isChecked = false
- showShortMessage("No USB Camera Detected!")
- } else {
- mCameraHelper.requestPermission(0)
- isUSB = true
- btnCalibrate.setVisibility(View.VISIBLE)
- // tvCalibrate.text = "Need Calibration"
- btnCalibrate.setOnClickListener {
- try {
- if (mCameraHelper == null || !mCameraHelper.isCameraOpened && !isUSB) {
- mCamera.parameters = getParameter()
- mCamera.takePicture(null, null, jpegCallBack)
- } else {
- val picPath: String = getFotoPath
- mCameraHelper.capturePicture(picPath
- ) { picPath: String? ->
- Handler(Looper.getMainLooper()).post {
- val imgFile = File(picPath)
- val myBitmap =
- BitmapFactory.decodeFile(imgFile.absolutePath)
- val (red, green, blue) = extractRGBFromCenter(
- myBitmap
- )
- Log.d("RGB", "R: $red, G: $green, B: $blue")
- val index = (0.2126 * red) + (0.7152 * green) + (0.0722)
- binding.tvCalibrate.text = "IKI LOH R=$red, G=$green, B=$blue \n Calibrate Result = $index"
- }
- }
- }
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
- }
- } else {
- tvCalibrate.setVisibility(View.GONE)
- btnCalibrate.setVisibility(View.GONE)
- mCameraHelper.closeCamera()
- loadCamera()
- isUSB = false
- }
- }
- if (context?.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
- requestPermissions(arrayOf(Manifest.permission.CAMERA), 100)
- }
- jpegCallBack = Camera.PictureCallback { bytes, cameras ->
- val outStream: FileOutputStream?
- try {
- val path: String = getFotoPath
- outStream = FileOutputStream(path)
- var bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
- val matrix = Matrix()
- matrix.postRotate(90f)
- bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.width, bmp.height, matrix, true)
- bmp.compress(Bitmap.CompressFormat.JPEG, 100, outStream)
- outStream.flush()
- outStream.close()
- // Update the current bitmap
- currentBitmap = bmp
- // Extract RGB from the center of the bitmap
- val (red, green, blue) = extractRGBFromCenter(bmp)
- Log.d("RGB", "R: $red, G: $green, B: $blue")
- // Update UI with RGB values (optional)
- binding.tvCalibrate.text = "Calibrate: R=$red, G=$green, B=$blue"
- navigation.previousBackStackEntry?.savedStateHandle?.set("path", path)
- navigation.popBackStack()
- } catch (e: FileNotFoundException) {
- e.message?.let { showShortMessage(it) }
- } catch (e: IOException) {
- e.message?.let { showShortMessage(it) }
- }
- refreshCamera()
- }
- }
- }
- private fun handleTouch(touchX: Float, touchY: Float) {
- val bitmap = if (::currentBitmap.isInitialized) {
- currentBitmap
- } else {
- return
- }
- val focusAreaSize = 100
- val left = (touchX - focusAreaSize / 2).toInt().coerceIn(0, bitmap.width - focusAreaSize)
- val top = (touchY - focusAreaSize / 2).toInt().coerceIn(0, bitmap.height - focusAreaSize)
- val right = (left + focusAreaSize).coerceIn(0, bitmap.width)
- val bottom = (top + focusAreaSize).coerceIn(0, bitmap.height)
- val focusAreaBitmap = Bitmap.createBitmap(bitmap, left, top, right - left, bottom - top)
- val (red, green, blue) = extractRGBFromCenter(focusAreaBitmap)
- Log.d("Focus Area RGB", "R: $red, G: $green, B: $blue")
- // Update UI with RGB values (optional)
- binding.tvCalibrate.text = "Focus Area RGB: R=$red, G=$green, B=$blue"
- }
- private fun extractRGBFromCenter(bitmap: Bitmap): Triple<Int, Int, Int> {
- val centerX = bitmap.width / 2
- val centerY = bitmap.height / 2
- val pixel = bitmap.getPixel(centerX, centerY)
- val red = Color.red(pixel)
- val green = Color.green(pixel)
- val blue = Color.blue(pixel)
- return Triple(red, green, blue)
- }
- private fun compressBitmap(bitmap: Bitmap, quality:Int):Bitmap{
- val stream = ByteArrayOutputStream()
- bitmap.compress(Bitmap.CompressFormat.WEBP, quality, stream)
- val byteArray = stream.toByteArray()
- return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
- }
- private fun calibrate(bitmap: Bitmap): ByteArray {
- val loader = context?.let { Loader(it).setLoader("Calibrating....") }
- loader?.show()
- val colorMatrix = ColorMatrix()
- val colorFilter: ColorFilter = ColorMatrixColorFilter(
- colorMatrix
- )
- val argbBitmap = Bitmap.createBitmap(
- bitmap.width, bitmap.height,
- Bitmap.Config.ARGB_8888
- )
- val canvas = Canvas(argbBitmap)
- val paint = Paint()
- paint.setColorFilter(colorFilter)
- canvas.drawBitmap(bitmap, 0f, 0f, paint)
- val width = bitmap.width
- val height = bitmap.height
- val componentsPerPixel = 3
- val totalPixels = width * height
- val totalBytes = totalPixels * componentsPerPixel
- val rgbValues = ByteArray(totalBytes)
- @ColorInt val argbPixels = IntArray(totalPixels)
- argbBitmap.getPixels(argbPixels, 0, width, 0, 0, width, height)
- for (i in 0 until totalPixels) {
- @ColorInt val argbPixel = argbPixels[i]
- val red : Int = Color.red(argbPixel)
- val green : Int = Color.green(argbPixel)
- val blue : Int = Color.blue(argbPixel)
- rgbValues[i * componentsPerPixel + 0] = red.toByte()
- rgbValues[i * componentsPerPixel + 1] = green.toByte()
- rgbValues[i * componentsPerPixel + 2] = blue.toByte()
- Log.e("TAG RGB R",red.toByte().toString())
- Log.e("TAG RGB G",red.toByte().toString())
- Log.e("TAG RGB B",red.toByte().toString())
- val r_final = 0.2126 * red
- val g_final = 0.7152 * green
- val b_final = 0.0722 * blue
- val valuecalibrate = r_final+g_final+b_final
- Log.e("TAG RGB FINAL ",valuecalibrate.toString())
- binding.tvCalibrate.text = "Calibrate : "+valuecalibrate.toString()
- }
- loader?.dismiss()
- return rgbValues
- }
- override fun onStart() {
- super.onStart()
- if (mCameraHelper != null) {
- mCameraHelper.registerUSB()
- }
- }
- override fun onStop() {
- super.onStop()
- if (mCameraHelper != null) {
- mCameraHelper.unregisterUSB()
- }
- }
- @get:Throws(IOException::class)
- private val getFotoPath: String
- private get() {
- var timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
- var imageFileName = "Agrilcam_" + timeStamp + "_"
- // String imageFileName = ;
- val storageDir = context?.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
- val image = File.createTempFile(imageFileName, ".jpg", storageDir)
- return image.absolutePath
- }
- private fun getParameter(): Camera.Parameters {
- val params = mCamera.parameters
- var bestSize: Camera.Size? = null
- val sizeList = mCamera.parameters.supportedPreviewSizes
- bestSize = sizeList[0]
- for (i in 1 until sizeList.size) {
- if (sizeList[i].width * sizeList[i].height > bestSize!!.width * bestSize.height) {
- bestSize = sizeList[i]
- }
- }
- val supportedPreviewFormats: List<Int> = params.supportedPreviewFormats
- val supportedPreviewFormatsIterator = supportedPreviewFormats.iterator()
- while (supportedPreviewFormatsIterator.hasNext()) {
- val previewFormat = supportedPreviewFormatsIterator.next()
- if (previewFormat == ImageFormat.YV12) {
- params.previewFormat = previewFormat
- }
- }
- //params.setPreviewSize(bestSize.width, bestSize.height);
- //params.setPictureSize(bestSize.width, bestSize.height);
- //params.setPreviewSize(bestSize.width, bestSize.height);
- //params.setPictureSize(bestSize.width, bestSize.height);
- params.setPreviewSize(640, 480)
- params.setPictureSize(640, 480)
- return params
- }
- private fun loadCamera() = try {
- mCamera = Camera.open()
- mCamera.parameters = getParameter()
- mCamera.setDisplayOrientation(90)
- mCamera.setPreviewTexture(mUVCCameraView.surfaceTexture)
- mCamera.startPreview()
- } catch (e: Exception) {
- showShortMessage("Camera:" + e.message)
- }
- private fun refreshCamera() {
- try {
- mCamera.stopPreview()
- } catch (e: Exception) {
- e.message?.let { showShortMessage(it) }
- }
- try {
- mCamera = Camera.open()
- mCamera.parameters = getParameter()
- mCamera.setDisplayOrientation(90)
- mCamera.setPreviewTexture(mUVCCameraView.surfaceTexture)
- mCamera.startPreview()
- } catch (e: Exception) {
- e.message?.let { showShortMessage(it) }
- }
- }
- override fun onDestroy() {
- super.onDestroy()
- if (mCameraHelper != null) {
- mCameraHelper.release()
- }
- }
- override fun onSurfaceCreated(view: CameraViewInterface?, surface: Surface?) {
- if (!isPreview && mCameraHelper.isCameraOpened()) {
- mCameraHelper.startPreview(mUVCCameraView);
- isPreview = true;
- }
- }
- override fun onSurfaceChanged(
- view: CameraViewInterface?,
- surface: Surface?,
- width: Int,
- height: Int
- ) {
- }
- override fun onSurfaceDestroy(view: CameraViewInterface?, surface: Surface?) {
- if (isPreview && mCameraHelper.isCameraOpened()) {
- mCameraHelper.stopPreview();
- isPreview = false;
- }
- }
- private val mDebugHandler: Handler = object : Handler(
- ) {
- override fun handleMessage(msg: Message) {
- var text = "mDebugHandler="
- when (msg.what) {
- MESSAGE_SHOW_TEXT -> if (msg.obj != null) {
- text += msg.obj.toString()
- }
- MESSAGE_FRAME_COUNT -> sendEmptyMessageDelayed(MESSAGE_FRAME_COUNT, 1000)
- else -> return
- }
- // mDebugInfo.setText(text)
- Log.e(TAG, "handleMessage: $text", )
- }
- }
- fun showDebugText(text: String?) {
- if (mInstance!!.mDebugHandler != null) {
- mInstance.mDebugHandler.sendMessage(
- mInstance.mDebugHandler.obtainMessage(
- MESSAGE_SHOW_TEXT,
- text
- )
- )
- }
- }
- companion object {
- private val TAG = "LOH HEH!!"
- private const val MESSAGE_SHOW_TEXT = 0
- private const val MESSAGE_FRAME_COUNT = 1
- }
- override fun getViewModel() = CameraViewModel::class.java
- override fun getFragmentBinding(
- inflater: LayoutInflater,
- container: ViewGroup?
- )= FragmentCameraBinding.inflate(inflater, container, false)
- override fun getFragmentRepository() = CameraRepository()
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement