Kotlin & Camera 2 中的 ImageReader - 从相机 reader 表面保存 .jpg 文件
ImageReader in Kotlin & Camera 2 - saving .jpg file from a camera reader surface
我正在尝试从我的 ImageReader.surface 中获取一张照片,我已将其添加为我的 CaptureSession 捕获请求的目标,我正在努力解决这个问题,因为我尝试使用 imageReader.acquireLatestImage() 但这个 alawys 将我引用到新 imagewriter.newInstance(...).dequeueinputimage 中的空对象枯萎,我在其中使用 ImageReader.surface 或者当我从 [=24 获取图像时=],这似乎是我的图像 reader 表面有问题,但我已经尝试了很多方法,但未能弄清楚如何在知道我在 reader ImageAVailablelistener:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.amjadshuk.roadanalysia, PID: 18251
java.lang.NullPointerException: Attempt to invoke virtual method 'android.media.Image$Plane[] android.media.Image.getPlanes()' on a null object reference
at com.amjadshuk.roadanalysia.MainActivity.onCreate$lambda-14(MainActivity.kt:482)
at com.amjadshuk.roadanalysia.MainActivity.$r8$lambda$NXtavG2wfAwvFvETtEdf5FaiLSE(Unknown Source:0)
at com.amjadshuk.roadanalysia.MainActivity$$ExternalSyntheticLambda0.onImageAvailable(Unknown Source:2)
at android.media.ImageReader$ListenerHandler.handleMessage(ImageReader.java:812)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8506)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1139)
我的全部代码:
@RequiresApi(Build.VERSION_CODES.P)
fun camera3() {
val handlerThread = HandlerThread("",HandlerThread.NORM_PRIORITY).apply {
start()
}
val handler = HandlerCompat.createAsync(handlerThread.looper).apply {
post {
//-----------------------------------------------------------------
GlobalScope.launch {
Looper.prepare()
val cm = getSystemService(Context.CAMERA_SERVICE) as CameraManager
val cc: CameraDevice.StateCallback = object : CameraDevice.StateCallback() {
@RequiresApi(Build.VERSION_CODES.Q)
override fun onOpened(cm: CameraDevice) {
findViewById<TextView>(R.id.textView29).text = "Camera 1 opened"
val surface1 = findViewById<SurfaceView>(R.id.surfaceView3).holder.surface
val cr = cm.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE).apply {
addTarget(surface1)
addTarget(imageReader.surface)
}.build()
val outputConfiguration = OutputConfiguration(surface1)
val outputConfiguration2 = OutputConfiguration(imageReader.surface)
val out = mutableListOf(outputConfiguration, outputConfiguration2)
cm.createCaptureSession(
SessionConfiguration(SessionConfiguration.SESSION_REGULAR,
out,
mainExecutor,
object : CameraCaptureSession.StateCallback() {
override fun onConfigured(p0: CameraCaptureSession) {
p0.setRepeatingRequest(
cr, object : CameraCaptureSession.CaptureCallback() {
override fun onCaptureCompleted(
session: CameraCaptureSession,
request: CaptureRequest,
result: TotalCaptureResult
) {
super.onCaptureCompleted(
session,
request,
result
)
Toast.makeText(applicationContext,"capture completed",Toast.LENGTH_SHORT).show()
}
},
null
)
}
override fun onConfigureFailed(p0: CameraCaptureSession) {
}
})
)
}
override fun onDisconnected(cm: CameraDevice) {
}
override fun onError(cm: CameraDevice, p1: Int) {
}
}
if (ActivityCompat.checkSelfPermission(
applicationContext,
Manifest.permission.CAMERA
) != PackageManager.PERMISSION_GRANTED
) {
this@MainActivity.requestPermissions(arrayOf(Manifest.permission.CAMERA), 9998)
}
if (cm.cameraIdList.isNotEmpty()) {
cm.getCameraCharacteristics(cm.cameraIdList.first())
.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)
cm.openCamera(cm.cameraIdList.first(), mainExecutor, cc)
}
val cameraAccessException = CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED)
cameraAccessException.printStackTrace()
val message = cameraAccessException.message!!
Log.e("camera2", "camera2: ${message}", cameraAccessException.fillInStackTrace())
Looper.loop()
}
}
}
}
创建时:
imageReader.setOnImageAvailableListener({
it.acquireLatestImage().close()
val image = imageReader.acquireLatestImage()
val byteArray = image.planes.last().buffer.array()
val file = FileOutputStream(File.createTempFile("image",".jpg",filesDir))
file.write(byteArray)
},null)
it.acquireLatestImage().close()
val image = imageReader.acquireLatestImage()
如果此代码是您实际拥有的代码,则您正在获取最新的可用图像,然后立即将其关闭。然后您尝试立即获取另一张图像。那时相机不太可能生成第二张图像,因此您会返回 null
。
只需删除第一个 acquireLatestImage 行。
我正在尝试从我的 ImageReader.surface 中获取一张照片,我已将其添加为我的 CaptureSession 捕获请求的目标,我正在努力解决这个问题,因为我尝试使用 imageReader.acquireLatestImage() 但这个 alawys 将我引用到新 imagewriter.newInstance(...).dequeueinputimage 中的空对象枯萎,我在其中使用 ImageReader.surface 或者当我从 [=24 获取图像时=],这似乎是我的图像 reader 表面有问题,但我已经尝试了很多方法,但未能弄清楚如何在知道我在 reader ImageAVailablelistener:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.amjadshuk.roadanalysia, PID: 18251
java.lang.NullPointerException: Attempt to invoke virtual method 'android.media.Image$Plane[] android.media.Image.getPlanes()' on a null object reference
at com.amjadshuk.roadanalysia.MainActivity.onCreate$lambda-14(MainActivity.kt:482)
at com.amjadshuk.roadanalysia.MainActivity.$r8$lambda$NXtavG2wfAwvFvETtEdf5FaiLSE(Unknown Source:0)
at com.amjadshuk.roadanalysia.MainActivity$$ExternalSyntheticLambda0.onImageAvailable(Unknown Source:2)
at android.media.ImageReader$ListenerHandler.handleMessage(ImageReader.java:812)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8506)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1139)
我的全部代码:
@RequiresApi(Build.VERSION_CODES.P)
fun camera3() {
val handlerThread = HandlerThread("",HandlerThread.NORM_PRIORITY).apply {
start()
}
val handler = HandlerCompat.createAsync(handlerThread.looper).apply {
post {
//-----------------------------------------------------------------
GlobalScope.launch {
Looper.prepare()
val cm = getSystemService(Context.CAMERA_SERVICE) as CameraManager
val cc: CameraDevice.StateCallback = object : CameraDevice.StateCallback() {
@RequiresApi(Build.VERSION_CODES.Q)
override fun onOpened(cm: CameraDevice) {
findViewById<TextView>(R.id.textView29).text = "Camera 1 opened"
val surface1 = findViewById<SurfaceView>(R.id.surfaceView3).holder.surface
val cr = cm.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE).apply {
addTarget(surface1)
addTarget(imageReader.surface)
}.build()
val outputConfiguration = OutputConfiguration(surface1)
val outputConfiguration2 = OutputConfiguration(imageReader.surface)
val out = mutableListOf(outputConfiguration, outputConfiguration2)
cm.createCaptureSession(
SessionConfiguration(SessionConfiguration.SESSION_REGULAR,
out,
mainExecutor,
object : CameraCaptureSession.StateCallback() {
override fun onConfigured(p0: CameraCaptureSession) {
p0.setRepeatingRequest(
cr, object : CameraCaptureSession.CaptureCallback() {
override fun onCaptureCompleted(
session: CameraCaptureSession,
request: CaptureRequest,
result: TotalCaptureResult
) {
super.onCaptureCompleted(
session,
request,
result
)
Toast.makeText(applicationContext,"capture completed",Toast.LENGTH_SHORT).show()
}
},
null
)
}
override fun onConfigureFailed(p0: CameraCaptureSession) {
}
})
)
}
override fun onDisconnected(cm: CameraDevice) {
}
override fun onError(cm: CameraDevice, p1: Int) {
}
}
if (ActivityCompat.checkSelfPermission(
applicationContext,
Manifest.permission.CAMERA
) != PackageManager.PERMISSION_GRANTED
) {
this@MainActivity.requestPermissions(arrayOf(Manifest.permission.CAMERA), 9998)
}
if (cm.cameraIdList.isNotEmpty()) {
cm.getCameraCharacteristics(cm.cameraIdList.first())
.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)
cm.openCamera(cm.cameraIdList.first(), mainExecutor, cc)
}
val cameraAccessException = CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED)
cameraAccessException.printStackTrace()
val message = cameraAccessException.message!!
Log.e("camera2", "camera2: ${message}", cameraAccessException.fillInStackTrace())
Looper.loop()
}
}
}
}
创建时:
imageReader.setOnImageAvailableListener({
it.acquireLatestImage().close()
val image = imageReader.acquireLatestImage()
val byteArray = image.planes.last().buffer.array()
val file = FileOutputStream(File.createTempFile("image",".jpg",filesDir))
file.write(byteArray)
},null)
it.acquireLatestImage().close()
val image = imageReader.acquireLatestImage()
如果此代码是您实际拥有的代码,则您正在获取最新的可用图像,然后立即将其关闭。然后您尝试立即获取另一张图像。那时相机不太可能生成第二张图像,因此您会返回 null
。
只需删除第一个 acquireLatestImage 行。