1

我正在创建一个以 .dng 格式拍摄照片以便处理它们的应用程序。我正在使用 camera2 API。我能够拍照并将它们保存到我的手机中,但格式为 .jpg。但是当我更改我的代码以使用 .dng 扩展名保存它们时,它会编译,在我的手机上显示预览,但是当拍摄照片时,我得到一个错误。我的代码中获取并保存图片的部分如下。

val reader = ImageReader.newInstance(1280, 720, ImageFormat.RAW_SENSOR, 1)

val outputSurfaces = ArrayList<Surface>(2)
outputSurfaces.add(reader.surface)
outputSurfaces.add(Surface(previewTextureView.surfaceTexture))

val captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE)
captureBuilder.addTarget(reader.surface)
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO)

val file = File("myPath/myImageName.dng")
var captureResult: CaptureResult? = null

我的听众:

val readerListener = object : ImageReader.OnImageAvailableListener {
    override fun onImageAvailable(reader: ImageReader) {
        var image: Image? = null
        var output: OutputStream? = null
        val dngCreator = DngCreator(cameraManager.getCameraCharacteristics("0"), captureResult)

        try {
             image = reader.acquireLatestImage()
             output = FileOutputStream(file)
             dngCreator.writeImage(output, image)
         } catch (e: FileNotFoundException) {
             e.printStackTrace()
         } catch (e: IOException) {
             e.printStackTrace()
         } finally {
             output?.close()
             image?.close()
         }
    }
}

reader.setOnImageAvailableListener(readerListener, backgroundHandler)

val captureListener = object : CameraCaptureSession.CaptureCallback() {
    override fun onCaptureCompleted(session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult) {
        captureResult = result
        super.onCaptureCompleted(session, request, result)
    }
}

最后,我通过以下方式捕获会话:

cameraDevice.createCaptureSession(outputSurfaces, object : CameraCaptureSession.StateCallback() {
    override fun onConfigured(session: CameraCaptureSession) {
        try {
             session.capture(captureBuilder.build(), captureListener, backgroundHandler)
         } catch (e: CameraAccessException) {
              e.printStackTrace()
         }
     }
     override fun onConfigureFailed(session: CameraCaptureSession) {}
}, backgroundHandler)

当我将图像保存为 jpeg 时,我遇到了一个警告和一个以前没有的错误:

W/CameraDevice-JV-0: Stream configuration failed due to: createSurfaceFromGbp:1106: Camera 0: No supported stream configurations with format 0x20 defined, failed to create output stream

E/CameraCaptureSession: Session 1: Failed to create capture session; configuration failed

为了保存 dng 文件,我更改了以下内容:

  • 我替换ImageFormat.JPEGImageFormat.RAW_SENSOR
  • 我将文件扩展名从 .jpg 更改为 .dng
  • 我没有使用dngCreator.writeImage(output, image),而是使用:
val buffer = image!!.planes[0].buffer
val bytes = ByteArray(buffer.capacity())
buffer.get(bytes)
output.write()

由于没有太多关于这个主题的信息,我不确定我的实现是否正确。

4

2 回答 2

1

这有点旧帖子,但对于原始图像,您不能将分辨率设置为任意值。假设您的设备可以进行 raw_sensor 读取,则必须将其设置为传感器大小。你需要做这样的事情。

val largestRaw = Collections.max(Arrays.asList(*map.getOutputSizes(ImageFormat.RAW_SENSOR)), CompareSizesByArea())

rawImageReader = ImageReader.newInstance(largestRaw.width, largestRaw.height, ImageFormat.RAW_SENSOR, /*maxImages*/ 5).apply { setOnImageAvailableListener(onRawImageAvailableListener, backgroundHandler) }

不幸的是,我现在在 kotlin 遇到:

java.lang.IllegalArgumentException:缺少标记 AsShotNeutral (c628) 的元数据字段

上面列出的过时的 java Camera2Raw 示例确实有效。

于 2020-04-25T10:24:50.707 回答
0

经过一番研究,我找到了一个实现,以便将使用 Camera2API 拍摄的图像保存在 .dng 文件中:

if (mImage.format == ImageFormat.RAW_SENSOR) {
    val dngCreator = DngCreator(mCharacteristics, mCaptureResult)
    var output: FileOutputStream? = null
    try {
        output = FileOutputStream(mFile)
        dngCreator.writeImage(output, mImage)
    } catch (e: IOException) {
         e.printStackTrace()
    } finally {
         mImage.close()
         closeOutput(output)
     }
}

在哪里 :

  • mCharacteristicsCameraCharacteristics,即描述CameraDevice
  • mCaptureResultCameraDevice经过加工后产生的CaptureRequest
  • mImage是函数中检索到的图像dequeuAndSaveImageimage = reader.get()!!.acquireNextImage()
  • mFile是将保存图像的文件,例如:
mFile = Environment
     .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
     "RAW_" + generateTimestamp()+ ".dng"

也许它会对某人有所帮助,但正如@Alex Cohn 所说,建议从官方示例github.com/googlesamples/android-Camera2Raw开始。它是用 Java 而不是 Kotlin 编写的,但如果需要,转换它并不难。

于 2019-07-24T15:54:09.497 回答