[英]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
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)
}
}
在哪里 :
mCharacteristics
是CameraCharacteristics
,即描述CameraDevice
的屬性mCaptureResult
由CameraDevice
在處理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.