【问题标题】:Auto Focus Modes Not Working In Samsung S8自动对焦模式在三星 S8 中不起作用
【发布时间】:2017-12-31 14:50:21
【问题描述】:

更新 2:任何对焦模式显然都不起作用

更新 1:问题似乎与我的三星 S8 设备有关。它适用于 Nexus 5X 和小米手机

我一直试图让FOCUS_MODE_CONTINUOUS_PICTURE 工作,但无济于事。我已通过getSupportedFocusModes() 确认我的设备支持连续自动拍照,但不知道为什么它不起作用。

这是我的代码,在startCamera() 中设置了连续自动对焦:

class CaptureReceiptFragment : Fragment(), CaptureReceiptContract.View {

private val MY_PERMISSIONS_REQUEST_CAMERA = 1

private var camera: Camera? = null
private var hasCameraPermission: Boolean? = null

private lateinit var preview: CameraPreview

override var presenter: CaptureReceiptContract.Presenter? = null

private val picture = Camera.PictureCallback { data, camera ->

    val pictureStorageDir = File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), getAppName())

    presenter?.saveReceipt(pictureStorageDir, data)


}

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    val root = inflater!!.inflate(R.layout.capturereceipt_frag, container, false)

    return root
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    hasCameraPermission = ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED

    if (hasCameraPermission!!) {
        showCameraErrorMsg()
    } else {
        capturereceipt_button_capturereceipt.setOnClickListener {
            captureReceipt()
        }
        startCameraOnCreate()
    }
}

override fun onResume() {
    super.onResume()
    presenter?.start()
    if (hasCameraPermission!!) {
        showCameraErrorMsg()
    } else {
        startCamera()
        setCameraRotation()
    }
}

override fun onPause() {
    super.onPause()
    camera?.release()
    camera = null
}

override fun gotoReceiptList() {
    //TODO
}

override fun goBack() {
    //TODO
}

private fun startCameraOnCreate() {
    preview = CameraPreview(context)
    capturereceipt_framelayout_viewfinder.addView(preview)
    startCamera()
}

private fun startCamera() {
    if (camera == null) {
        camera = Camera.open()
        if (camera == null) {
            showCameraErrorMsg()
        } else {
            val params: Camera.Parameters? = camera!!.parameters
            if (params!!.getSupportedFocusModes()
                    .contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
                params.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE;
            }
            camera?.parameters = params
            preview.camera = camera
            capturereceipt_textview_cameraerrormsg.visibility = View.GONE
            capturereceipt_framelayout_viewfinder.visibility = View.VISIBLE
        }
    }
}

private fun showCameraErrorMsg() {
    capturereceipt_textview_cameraerrormsg.visibility = View.VISIBLE
    capturereceipt_framelayout_viewfinder.visibility = View.GONE
}

override fun captureReceipt() {
    camera?.takePicture(null, null, picture)
}

private fun getOutputPictureFile(): File? {
    val appName = getAppName()

    val pictureStorageDir = File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), appName)

    if (!pictureStorageDir.exists()) {
        pictureStorageDir.mkdirs()
    }

    val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
    return File(pictureStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg")
}

private fun getAppName(): String {
    val appInfo = context.getApplicationInfo()
    val stringId = appInfo.labelRes
    if (stringId == 0) {
        return appInfo.nonLocalizedLabel.toString()
    } else {
        return this.getString(stringId)
    }
}

fun setCameraDisplayOrientation() {
    val info = Camera.CameraInfo()
    Camera.getCameraInfo(CAMERA_FACING_BACK, info)
    val rotation = activity.windowManager.defaultDisplay.rotation
    var degrees = 0
    when (rotation) {
        Surface.ROTATION_0 -> degrees = 0
        Surface.ROTATION_90 -> degrees = 90
        Surface.ROTATION_180 -> degrees = 180
        Surface.ROTATION_270 -> degrees = 270
    }
    var result: Int
    if (info.facing == CAMERA_FACING_FRONT) {
        result = (info.orientation + degrees) % 360
        result = (360 - result) % 360  // compensate the mirror
    } else {  // back-facing
        result = (info.orientation - degrees + 360) % 360
    }
    camera?.setDisplayOrientation(result);
}

fun setCameraRotation() {
    val info: Camera.CameraInfo = Camera.CameraInfo()
    Camera.getCameraInfo(CAMERA_FACING_BACK, info)
    val rotation = activity.windowManager.defaultDisplay.rotation
    var degrees = 0
    when(rotation) {
        Surface.ROTATION_0 -> degrees = 0
        Surface.ROTATION_90 -> degrees = 90
        Surface.ROTATION_180 -> degrees = 180
        Surface.ROTATION_270 -> degrees = 270
    }
    val rotate = (info.orientation - degrees + 360) % 360
    camera?.setDisplayOrientation(rotate)
    val params: Camera.Parameters = camera!!.parameters
    params.setRotation(rotate)
    camera?.parameters = params
}

companion object {
    @JvmStatic fun newInstance(): CaptureReceiptFragment {
        return CaptureReceiptFragment()
    }
}

}

任何帮助将不胜感激。谢谢!

【问题讨论】:

  • 为什么投反对票?这似乎是一个合法的问题
  • @Michael 是的,虽然解决方案不起作用,但相关。我已经想通了;将在这里发布答案

标签: android kotlin android-camera samsung-mobile galaxy


【解决方案1】:

我终于想通了——看来三星 S8 的自动对焦模式参数应该设置不同。

这是我尝试失败的方法:

  1. 设置任何自动对焦模式(AUTO、CONTINUOUS_PICTURE、INFINITY) 开始预览之前
  2. 计划camera.autoFocus() 运行每个 在 camera.open 之后的一秒

这是我尝试过的有效方法:

  1. 将持续焦点或camera.autoFocus() 放在按钮上的点击中
  2. camera.open() 之后将连续对焦设置延迟 1 秒

#2 我的代码:

private val autoFocusExecutor = ScheduledThreadPoolExecutor(1)

fun startCamera() {
    if (camera == null) {
        camera = Camera.open()
        if (camera == null) {
            showCameraErrorMsg()
        } else {
            preview.camera = camera
            capturereceipt_textview_cameraerrormsg.visibility = View.GONE
            capturereceipt_framelayout_viewfinder.visibility = View.VISIBLE

            autoFocusExecutor.schedule(Sc{
                val params: Camera.Parameters = camera!!.parameters
                if (params.getSupportedFocusModes()
                        .contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
                    //TODO: Auto focus not working
                    params.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE
                }
                camera?.parameters = params
            }, 1000, TimeUnit.MILLISECONDS)
        }
    }
}

【讨论】:

  • 我们在三星 S6 上遇到了同样的问题,这已解决!
  • “持续聚焦”是指每 X 秒调用一次camera.autoFocus()?关于延迟获得支持的对焦模式,这对我没有帮助(在 SGS7 和 Pixel 2 上测试)。它为我返回了相同的一小部分可用对焦模式(Pixel 2 为“固定”,SGS7 为“固定”、“无限”)。
  • @androiddeveloper 不,自动对焦是一种不同的对焦方式,与 FOCUS_MODE_CONTINUOUS_PICTURE 不同。
  • 那么,我想知道的是,如果三星不支持 FOCUS_MODE_CONTINUOUS_PICTURE,他们的后备方案是什么?
  • @BrillPappin 我注意到他们几乎不提供任何这些模式。最多2个或类似的东西。所以,我们只是时不时地调用autoFocus这个函数。
【解决方案2】:

我在使用三星 J7 Prime 时遇到了同样的问题,代码可以正常工作,但相机焦点已修复。使用处理程序设置焦点模式为我解决了这个问题:

Handler().post { 
    camera.apply {
        val params = camera.parameters

        if (params.supportedFocusModes?.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) == true) {
            params.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE
            camera.parameters = params
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    • 2018-01-28
    • 2015-07-11
    • 1970-01-01
    相关资源
    最近更新 更多