title: Taking a dng picture using the Camera2 API
body: <p>I'm creating an app that takes pictures in .dng format in order to process them. I'm using the camera2 API. I was able to take pictures and save them into my phone, but in .jpg format. But when I change my code in order to save them with .dng extension, it compiles, show me the preview on my phone, but when the picture is taken, I get an error. The part of my code that takes and saves the picture is as follows.</p>
  
  <pre class="lang-java prettyprint-override"><code>val reader = ImageReader.newInstance(1280, 720, ImageFormat.RAW_SENSOR, 1)
  
  val outputSurfaces = ArrayList&lt;Surface&gt;(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
  </code></pre>
  
  <p>And my listeners : </p>
  
  <pre class="lang-java prettyprint-override"><code>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)
      }
  }
  
  </code></pre>
  
  <p>And finally I capture the session with:</p>
  
  <pre class="lang-java prettyprint-override"><code>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)
  </code></pre>
  
  <p>I'm having one warning and one error that I didn't have before, when I was saving the image as jpeg: </p>
  
  <pre class="lang-java prettyprint-override"><code>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
  </code></pre>
  
  <p>Things that I changed in order to save a dng file are :</p>
  
  <ul>
  <li>I replaced <code>ImageFormat.JPEG</code> with <code>ImageFormat.RAW_SENSOR</code></li>
  <li>I changed the file extension from .jpg to .dng</li>
  <li>Instead of using <code>dngCreator.writeImage(output, image)</code>, I used :</li>
  </ul>
  
  <pre class="lang-java prettyprint-override"><code>val buffer = image!!.planes[0].buffer
  val bytes = ByteArray(buffer.capacity())
  buffer.get(bytes)
  output.write()
  </code></pre>
  
  <p>Since there is not a lot of information about this subject, I'm not sure if my implementation is correct.</p>