簡體   English   中英

使用 Camera2 API 拍攝 dng 圖片

[英]Taking a dng picture using the Camera2 API

我正在創建一個以 .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.JPEG替換了ImageFormat.RAW_SENSOR
  • 我將文件擴展名從 .jpg 更改為 .dng
  • 我沒有使用dngCreator.writeImage(output, image) ,而是使用了:
val buffer = image!!.planes[0].buffer
val bytes = ByteArray(buffer.capacity())
buffer.get(bytes)
output.write()

由於關於這個主題的信息不多,我不確定我的實現是否正確。

這是一篇舊帖子,但對於原始圖像,您不能將分辨率設置為任意值。 假設您的設備可以進行 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 示例確實有效。

經過一番研究,我找到了一個實現,以便將使用 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是在函數dequeuAndSaveImage檢索到的image = reader.get()!!.acquireNextImage()image = reader.get()!!.acquireNextImage()
  • mFile是保存圖像的文件,例如:
mFile = Environment
     .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
     "RAW_" + generateTimestamp()+ ".dng"

也許它會幫助某人,但正如@Alex Cohn 所說,建議從官方示例github.com/googlesamples/android-Camera2Raw開始。 它是用 Java 編寫的,而不是用 Kotlin 編寫的,但如果需要,轉換它並不難。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM