diff --git a/README.md b/README.md index 108e227..deccc7c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # THETA X Plug-in : Camera API Sample -Version: 1.3.1 +Version: 1.4.0 This sample project shows how to implement a plug-in using Camera API for RICOH THETA X. The program language is Kotlin, please checkout [java branch](https://github.com/ricohapi/theta-plugin-camera-api-sample-x/tree/java) to see Java code. @@ -33,6 +33,7 @@ The program language is Kotlin, please checkout [java branch](https://github.com > * ⑥ Spinner to choose RIC_SHOOTING_MODE for video mode > * ⑦ Spinner to choose RIC_PROC_STITCHING > * ⑧ Spinner to choose RIC_PROC_ZENITH_CORRECTION + > * ⑩ Spinner to choose ImageFormat.JPEG or ImageFormat.NV21 for image mode > * Shutter Key : press to execute take picture ; same function as ② > * Mode Key : long press to exit plug-in @@ -78,7 +79,7 @@ The program language is Kotlin, please checkout [java branch](https://github.com ```gradle dependencies { ... - implementation 'com.theta360:pluginlibrary:3.2.0' + implementation 'com.theta360:pluginlibrary:3.3.0' ... } ``` @@ -252,6 +253,14 @@ The program language is Kotlin, please checkout [java branch](https://github.com | RicPreview3840:2160 | 3840 | 2160 | | RicPreview5760 | 5760 | 2880 | +### Capture Image as NV21 Format (available Version 2.30.0 or later) + +* Image Format can be set to ImageFormat.NV21 with following. + + ```java + p.setPictureFormat(ImageFormat.NV21) + ``` + ## See Also diff --git a/app/build.gradle b/app/build.gradle index 485f18e..71f7c56 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { applicationId "com.theta360.sample.camera" minSdkVersion 26 targetSdkVersion 29 - versionCode 8 - versionName "1.3.1" + versionCode 9 + versionName "1.4.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } @@ -35,7 +35,7 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:2.0.4' - implementation 'com.theta360:pluginlibrary:3.2.0' + implementation 'com.theta360:pluginlibrary:3.3.0' //testImplementation 'junit:junit:4.+' //androidTestImplementation 'com.android.support.test:runner:1.0.2' //androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' diff --git a/app/src/main/java/com/theta360/sample/camera/MainActivity.kt b/app/src/main/java/com/theta360/sample/camera/MainActivity.kt index 280151f..981f092 100644 --- a/app/src/main/java/com/theta360/sample/camera/MainActivity.kt +++ b/app/src/main/java/com/theta360/sample/camera/MainActivity.kt @@ -1,5 +1,6 @@ package com.theta360.sample.camera +import android.graphics.ImageFormat import android.graphics.SurfaceTexture import android.os.Bundle import android.os.Handler @@ -59,6 +60,8 @@ class MainActivity : PluginActivity(), MediaRecorder.OnInfoListener { private var isLongShutter: Boolean = false private var isLowPowerPreview: Boolean = false + private var isNV21Available: Boolean = false + private var isJPEG: Boolean = true private var mLcdBrightness: Int = 64 private var mLedPowerBrightness: IntArray = intArrayOf(0, 0, 0, 64) //(dummy,R,G,B) @@ -85,6 +88,7 @@ class MainActivity : PluginActivity(), MediaRecorder.OnInfoListener { val spinner_ric_shooting_mode_video: Spinner = findViewById(R.id.spinner_ric_shooting_mode_video) val spinner_ric_proc_stitching: Spinner = findViewById(R.id.spinner_ric_proc_stitching) val spinner_ric_proc_zenith_correction: Spinner = findViewById(R.id.spinner_ric_proc_zenith_correction) + val spinner_picture_format: Spinner = findViewById(R.id.spinner_picture_format) //KeyCallback setKeyCallback(object : KeyCallback { @@ -155,6 +159,7 @@ class MainActivity : PluginActivity(), MediaRecorder.OnInfoListener { //firmware check val version = ThetaInfo.getThetaFirmwareVersion().replace(".", "").toFloat() isLowPowerPreview = if (version >= 1200) true else false //15fps preview available with fw1.20 or later + isNV21Available = if (version >= 2300) true else false //NV21 picture format available with fw2.30 or later //Spinner : set Camera Parameters setSpinner(spinner_ric_shooting_mode_preview, getResources().getStringArray( @@ -165,6 +170,7 @@ class MainActivity : PluginActivity(), MediaRecorder.OnInfoListener { spinner_ric_shooting_mode_video.setSelection(1) //RicMovieRecording3840 spinner_ric_proc_stitching.setSelection(2) //RicDynamicStitchingAuto spinner_ric_proc_zenith_correction.setSelection(1) //RicZenithCorrectionOnAuto + spinner_picture_format.setSelection(0) //ImageFormat.JPEG //TextureView : show preview val texture_view = findViewById(R.id.texture_view) @@ -260,12 +266,13 @@ class MainActivity : PluginActivity(), MediaRecorder.OnInfoListener { return true } - private fun getOutputMediaFile(): File? { + private fun getOutputMediaFile(isJPEG: Boolean): File? { if (!setFolderPath()) { return null } - mFilepath = mPath + "PC" + SimpleDateFormat("HHmmss").format(Date()) + ".JPG" - Log.i(TAG, "JPEG file path = " + mFilepath) + mFilepath = mPath + "PC" + SimpleDateFormat("HHmmss").format(Date()) + mFilepath += if(isJPEG) ".JPG" else ".NV21" + Log.i(TAG, "file path = " + mFilepath) return File(mFilepath) } @@ -347,7 +354,7 @@ class MainActivity : PluginActivity(), MediaRecorder.OnInfoListener { }, Camera.PictureCallback{ data, _ -> Log.i(TAG,"receive jpeg callback") - val pictureFile: File = getOutputMediaFile() ?: run { + val pictureFile: File = getOutputMediaFile(isJPEG) ?: run { Log.e(TAG, "cannot create file") return@PictureCallback } @@ -499,6 +506,8 @@ class MainActivity : PluginActivity(), MediaRecorder.OnInfoListener { val ric_shooting_mode_video: String = findViewById(R.id.spinner_ric_shooting_mode_video).selectedItem.toString() val ric_proc_stitching: String = findViewById(R.id.spinner_ric_proc_stitching).selectedItem.toString() val ric_proc_zenith_correction: String = findViewById(R.id.spinner_ric_proc_zenith_correction).selectedItem.toString() + val picture_format: String = findViewById(R.id.spinner_picture_format).selectedItem.toString() + val picture_format_array: Array = resources.getStringArray(R.array.PICTURE_FORMAT) val p = mCamera!!.getParameters() p.set(RIC_PROC_STITCHING, ric_proc_stitching) @@ -529,6 +538,14 @@ class MainActivity : PluginActivity(), MediaRecorder.OnInfoListener { p.set(RIC_SHOOTING_MODE, ric_shooting_mode_image) isMultiShot = if(ric_shooting_mode_image.equals("RicStillCaptureStd")) false else true p.setPictureSize(11008, 5504) //11008*5504 or 5504*2752 + if (picture_format == picture_format_array[0]) { //JPEG or NV21 + p.pictureFormat = ImageFormat.JPEG + isJPEG = true + } + else { + p.pictureFormat = ImageFormat.NV21 + isJPEG = false + } } MODE.VIDEO -> { p.set(RIC_SHOOTING_MODE, ric_shooting_mode_video) @@ -561,6 +578,7 @@ class MainActivity : PluginActivity(), MediaRecorder.OnInfoListener { findViewById(R.id.spinner_ric_shooting_mode_video).isEnabled = flag findViewById(R.id.spinner_ric_proc_stitching).isEnabled = flag findViewById(R.id.spinner_ric_proc_zenith_correction).isEnabled = flag + findViewById(R.id.spinner_picture_format).isEnabled = if (isNV21Available) flag else false } fun enableButton(button: Button, flag: Boolean) { diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index b733a81..96e61b0 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -26,7 +26,7 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/button_image" - app:layout_constraintTop_toBottomOf="@+id/spinner_ric_proc_zenith_correction" /> + app:layout_constraintTop_toBottomOf="@+id/spinner_picture_format" />