From 51cefe4157132865fe3c4954bcee9d5d3d9ab5ad Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Mon, 3 Feb 2025 15:49:24 -0800 Subject: [PATCH 1/2] Add support for HEIC_ULTRAHDR --- app/build.gradle.kts | 3 +- gradle.properties | 1 + samples/camera/camera2/build.gradle.kts | 4 +++ .../Camera2HeicUltraHDRCapture.kt | 26 +++++++++++++++ .../imagecapture/Camera2UltraHDRCapture.kt | 33 ++++++++++--------- 5 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 samples/camera/camera2/src/main/java/com/example/platform/camera/imagecapture/Camera2HeicUltraHDRCapture.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 0848349e..eacf53f6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -23,7 +23,8 @@ plugins { android { namespace = "com.example.platform" - compileSdk = 35 + compileSdkPreview = "Baklava" + defaultConfig { applicationId = "com.example.platform" diff --git a/gradle.properties b/gradle.properties index 909ce195..0447994c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -63,3 +63,4 @@ android.defaults.buildfeatures.aidl=false android.defaults.buildfeatures.renderscript=false android.defaults.buildfeatures.resvalues=false android.defaults.buildfeatures.shaders=false +android.suppressUnsupportedCompileSdk=35 diff --git a/samples/camera/camera2/build.gradle.kts b/samples/camera/camera2/build.gradle.kts index 1f540082..8a35f386 100644 --- a/samples/camera/camera2/build.gradle.kts +++ b/samples/camera/camera2/build.gradle.kts @@ -33,6 +33,10 @@ android { } viewBinding.isEnabled = true + compileSdkPreview = "Baklava" + defaultConfig { + targetSdkPreview = "Baklava" + } } dependencies { diff --git a/samples/camera/camera2/src/main/java/com/example/platform/camera/imagecapture/Camera2HeicUltraHDRCapture.kt b/samples/camera/camera2/src/main/java/com/example/platform/camera/imagecapture/Camera2HeicUltraHDRCapture.kt new file mode 100644 index 00000000..1b819d49 --- /dev/null +++ b/samples/camera/camera2/src/main/java/com/example/platform/camera/imagecapture/Camera2HeicUltraHDRCapture.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.platform.camera.imagecapture + +import android.graphics.ImageFormat +import android.os.Build +import androidx.annotation.RequiresApi + +@RequiresApi(Build.VERSION_CODES.BAKLAVA) +class Camera2HeicUltraHDRCapture : Camera2UltraHDRCapture() { + override val ULTRAHDR_FORMAT = ImageFormat.HEIC_ULTRAHDR +} diff --git a/samples/camera/camera2/src/main/java/com/example/platform/camera/imagecapture/Camera2UltraHDRCapture.kt b/samples/camera/camera2/src/main/java/com/example/platform/camera/imagecapture/Camera2UltraHDRCapture.kt index 3b0d008e..cb91cfd7 100644 --- a/samples/camera/camera2/src/main/java/com/example/platform/camera/imagecapture/Camera2UltraHDRCapture.kt +++ b/samples/camera/camera2/src/main/java/com/example/platform/camera/imagecapture/Camera2UltraHDRCapture.kt @@ -44,11 +44,9 @@ import android.view.SurfaceView import android.view.View import android.view.ViewGroup import androidx.activity.result.contract.ActivityResultContracts -import androidx.annotation.RequiresApi import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.toDrawable import androidx.core.os.bundleOf -import androidx.exifinterface.media.ExifInterface import androidx.fragment.app.Fragment import androidx.fragment.app.commit import androidx.lifecycle.lifecycleScope @@ -76,14 +74,16 @@ import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException import kotlin.coroutines.suspendCoroutine -@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) -class Camera2UltraHDRCapture : Fragment() { +@RequiresApi(Build.VERSION_CODES.BAKLAVA) +open class Camera2UltraHDRCapture : Fragment() { /** * Android ViewBinding. */ private var _binding: Camera2UltrahdrCaptureBinding? = null private val binding get() = _binding!! + protected open val ULTRAHDR_FORMAT = ImageFormat.JPEG_R + /** * Detects, characterizes, and connects to a CameraDevice (used for all camera operations). */ @@ -303,13 +303,13 @@ class Camera2UltraHDRCapture : Fragment() { private fun setUpImageReader() { // Initialize an image reader which will be used to capture still photos - val pixelFormat = ImageFormat.JPEG_R + val pixelFormat = ULTRAHDR_FORMAT val configMap = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP) configMap?.let { config -> config.getOutputSizes(pixelFormat).maxByOrNull { it.height * it.width } ?.let { size -> imageReader = ImageReader.newInstance( - size.width, size.height, pixelFormat, IMAGE_BUFFER_SIZE, + size.width, size.height, ULTRAHDR_FORMAT, IMAGE_BUFFER_SIZE, ) } } @@ -324,13 +324,9 @@ class Camera2UltraHDRCapture : Fragment() { takePhoto().use { result -> Log.d(TAG, "Result received: $result") - // Save the result to disk, update EXIF metadata with orientation info + // Save the result to disk val output = saveResult(result) Log.d(TAG, "Image saved: ${output.absolutePath}") - val exif = ExifInterface(output.absolutePath) - exif.setAttribute(ExifInterface.TAG_ORIENTATION, result.orientation.toString()) - exif.saveAttributes() - Log.d(TAG, "EXIF metadata saved: ${output.absolutePath}") // Display the photo taken to user lifecycleScope.launch(Dispatchers.Main) { @@ -355,7 +351,7 @@ class Camera2UltraHDRCapture : Fragment() { // Query the available output formats. val formats = c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)?.outputFormats - val canEncodeUltraHDR = formats?.contains(ImageFormat.JPEG_R) ?: false + val canEncodeUltraHDR = formats?.contains(ULTRAHDR_FORMAT) ?: false return canEncodeUltraHDR } @@ -499,6 +495,7 @@ class Camera2UltraHDRCapture : Fragment() { val request = session.device.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE) .apply { addTarget(imageReader.surface) } + request.set(CaptureRequest.JPEG_ORIENTATION, relativeOrientation.value ?: 0) session.capture( request.build(), @@ -584,7 +581,7 @@ class Camera2UltraHDRCapture : Fragment() { val buffer = result.image.planes[0].buffer val bytes = ByteArray(buffer.remaining()).apply { buffer.get(this) } try { - val output = createFile(requireContext()) + val output = createFile(requireContext(), ULTRAHDR_FORMAT) FileOutputStream(output).use { it.write(bytes) } cont.resume(output) } catch (exc: IOException) { @@ -635,9 +632,13 @@ class Camera2UltraHDRCapture : Fragment() { * * @return [File] created. */ - private fun createFile(context: Context): File { + private fun createFile(context: Context, format: Int): File { val sdf = SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS", Locale.US) - return File(context.filesDir, "IMG_${sdf.format(Date())}.jpg") + var fileType = ".jpg" + if (format != ImageFormat.JPEG_R) { + fileType = ".heic" + } + return File(context.filesDir, "IMG_${sdf.format(Date())}" + fileType) } } -} \ No newline at end of file +} From 5c7a1f38ec1f81a48896c7edd4e3421f7371749a Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Tue, 11 Mar 2025 15:25:42 -0700 Subject: [PATCH 2/2] Update samples/camera/camera2/src/main/java/com/example/platform/camera/imagecapture/Camera2UltraHDRCapture.kt Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../platform/camera/imagecapture/Camera2UltraHDRCapture.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/camera/camera2/src/main/java/com/example/platform/camera/imagecapture/Camera2UltraHDRCapture.kt b/samples/camera/camera2/src/main/java/com/example/platform/camera/imagecapture/Camera2UltraHDRCapture.kt index cb91cfd7..1b400255 100644 --- a/samples/camera/camera2/src/main/java/com/example/platform/camera/imagecapture/Camera2UltraHDRCapture.kt +++ b/samples/camera/camera2/src/main/java/com/example/platform/camera/imagecapture/Camera2UltraHDRCapture.kt @@ -634,9 +634,9 @@ open class Camera2UltraHDRCapture : Fragment() { */ private fun createFile(context: Context, format: Int): File { val sdf = SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS", Locale.US) - var fileType = ".jpg" - if (format != ImageFormat.JPEG_R) { - fileType = ".heic" + fileType = when (format) { + ImageFormat.JPEG_R -> ".jpg" + else -> ".heic" } return File(context.filesDir, "IMG_${sdf.format(Date())}" + fileType) }