diff --git a/Application/build.gradle b/Application/build.gradle index 2a87c6b..4277b77 100644 --- a/Application/build.gradle +++ b/Application/build.gradle @@ -36,10 +36,14 @@ android { compileSdk 33 defaultConfig { - minSdkVersion 21 + minSdkVersion 24 targetSdkVersion 27 } + lint { + baseline = file("lint-baseline.xml") + } + compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 diff --git a/Application/release/output-metadata.json b/Application/release/output-metadata.json new file mode 100644 index 0000000..fbc651e --- /dev/null +++ b/Application/release/output-metadata.json @@ -0,0 +1,20 @@ +{ + "version": 3, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "com.xypower.mppreview", + "variantName": "release", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "attributes": [], + "versionCode": 1, + "versionName": "1.0", + "outputFile": "Application-release.apk" + } + ], + "elementType": "File" +} \ No newline at end of file diff --git a/Application/src/main/AndroidManifest.xml b/Application/src/main/AndroidManifest.xml index f948c6a..3441f94 100644 --- a/Application/src/main/AndroidManifest.xml +++ b/Application/src/main/AndroidManifest.xml @@ -16,7 +16,7 @@ --> @@ -34,7 +34,8 @@ android:icon="@drawable/ic_launcher" android:theme="@style/MaterialTheme"> - diff --git a/Application/src/main/java/com/example/android/camera2raw/AutoFitTextureView.java b/Application/src/main/java/com/xypower/mppreview/AutoFitTextureView.java similarity index 98% rename from Application/src/main/java/com/example/android/camera2raw/AutoFitTextureView.java rename to Application/src/main/java/com/xypower/mppreview/AutoFitTextureView.java index e02e8b8..f3940f3 100644 --- a/Application/src/main/java/com/example/android/camera2raw/AutoFitTextureView.java +++ b/Application/src/main/java/com/xypower/mppreview/AutoFitTextureView.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.example.android.camera2raw; +package com.xypower.mppreview; import android.content.Context; import android.util.AttributeSet; diff --git a/Application/src/main/java/com/example/android/camera2raw/Camera2RawFragment.java b/Application/src/main/java/com/xypower/mppreview/Camera2RawFragment.java similarity index 95% rename from Application/src/main/java/com/example/android/camera2raw/Camera2RawFragment.java rename to Application/src/main/java/com/xypower/mppreview/Camera2RawFragment.java index 7bd20e7..92e479c 100644 --- a/Application/src/main/java/com/example/android/camera2raw/Camera2RawFragment.java +++ b/Application/src/main/java/com/xypower/mppreview/Camera2RawFragment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.example.android.camera2raw; +package com.xypower.mppreview; import android.Manifest; import android.app.Activity; @@ -66,6 +66,7 @@ import android.view.Surface; import android.view.TextureView; import android.view.View; import android.view.ViewGroup; +import android.widget.Switch; import android.widget.Toast; import java.io.File; @@ -301,13 +302,6 @@ public class Camera2RawFragment extends Fragment */ private RefCountedAutoCloseable mJpegImageReader; - /** - * A reference counted holder wrapping the {@link ImageReader} that handles RAW image captures. - * This is used to allow us to clean up the {@link ImageReader} when all background tasks using - * its {@link Image}s have completed. - */ - private RefCountedAutoCloseable mRawImageReader; - /** * Whether or not the currently configured camera device is fixed-focus. */ @@ -323,11 +317,6 @@ public class Camera2RawFragment extends Fragment */ private final TreeMap mJpegResultQueue = new TreeMap<>(); - /** - * Request ID to {@link ImageSaver.ImageSaverBuilder} mapping for in-progress RAW captures. - */ - private final TreeMap mRawResultQueue = new TreeMap<>(); - /** * {@link CaptureRequest.Builder} for the camera preview */ @@ -411,20 +400,6 @@ public class Camera2RawFragment extends Fragment }; - /** - * This a callback object for the {@link ImageReader}. "onImageAvailable" will be called when a - * RAW image is ready to be saved. - */ - private final ImageReader.OnImageAvailableListener mOnRawImageAvailableListener - = new ImageReader.OnImageAvailableListener() { - - @Override - public void onImageAvailable(ImageReader reader) { - dequeueAndSaveImage(mRawResultQueue, mRawImageReader); - } - - }; - /** * A {@link CameraCaptureSession.CaptureCallback} that handles events for the preview and * pre-capture sequence. @@ -513,9 +488,6 @@ public class Camera2RawFragment extends Fragment public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) { String currentDateTime = generateTimestamp(); - File rawFile = new File(Environment. - getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), - "RAW_" + currentDateTime + ".dng"); File jpegFile = new File(Environment. getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "JPEG_" + currentDateTime + ".jpg"); @@ -523,15 +495,12 @@ public class Camera2RawFragment extends Fragment // Look up the ImageSaverBuilder for this request and update it with the file name // based on the capture start time. ImageSaver.ImageSaverBuilder jpegBuilder; - ImageSaver.ImageSaverBuilder rawBuilder; int requestId = (int) request.getTag(); synchronized (mCameraStateLock) { jpegBuilder = mJpegResultQueue.get(requestId); - rawBuilder = mRawResultQueue.get(requestId); } if (jpegBuilder != null) jpegBuilder.setFile(jpegFile); - if (rawBuilder != null) rawBuilder.setFile(rawFile); } @Override @@ -545,23 +514,15 @@ public class Camera2RawFragment extends Fragment // Look up the ImageSaverBuilder for this request and update it with the CaptureResult synchronized (mCameraStateLock) { jpegBuilder = mJpegResultQueue.get(requestId); - rawBuilder = mRawResultQueue.get(requestId); if (jpegBuilder != null) { jpegBuilder.setResult(result); sb.append("Saving JPEG as: "); sb.append(jpegBuilder.getSaveLocation()); } - if (rawBuilder != null) { - rawBuilder.setResult(result); - if (jpegBuilder != null) sb.append(", "); - sb.append("Saving RAW as: "); - sb.append(rawBuilder.getSaveLocation()); - } // If we have all the results necessary, save the image to a file in the background. handleCompletionLocked(requestId, jpegBuilder, mJpegResultQueue); - handleCompletionLocked(requestId, rawBuilder, mRawResultQueue); finishedCaptureLocked(); } @@ -575,7 +536,6 @@ public class Camera2RawFragment extends Fragment int requestId = (int) request.getTag(); synchronized (mCameraStateLock) { mJpegResultQueue.remove(requestId); - mRawResultQueue.remove(requestId); finishedCaptureLocked(); } showToast("Capture failed!"); @@ -612,6 +572,17 @@ public class Camera2RawFragment extends Fragment // view.findViewById(R.id.info).setOnClickListener(this); mTextureView = (AutoFitTextureView) view.findViewById(R.id.texture); + view.findViewById(R.id.hdr).setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + closeCamera(); + // stopBackgroundThread(); + // startBackgroundThread(); + openCamera(); + } + }); + // Setup a new OrientationEventListener. This is used to handle rotation events like a // 180 degree rotation that do not normally trigger a call to onCreate to do view re-layout // or otherwise cause the preview TextureView's size to change. @@ -701,19 +672,23 @@ public class Camera2RawFragment extends Fragment show(getFragmentManager(), "dialog"); return false; } + + View rootView = getView(); + Switch hdrSwitch = (Switch)(rootView.findViewById(R.id.hdr)); + + boolean hdrChecked = hdrSwitch.isChecked(); + final String expectedCameraId = hdrChecked ? "1" : "0"; try { // Find a CameraDevice that supports RAW captures, and configure state. for (String cameraId : manager.getCameraIdList()) { - CameraCharacteristics characteristics - = manager.getCameraCharacteristics(cameraId); - // We only use a camera that supports RAW in this sample. - if (!contains(characteristics.get( - CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES), - CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) { + if (!TextUtils.equals(cameraId, expectedCameraId)) { continue; } + CameraCharacteristics characteristics + = manager.getCameraCharacteristics(cameraId); + StreamConfigurationMap map = characteristics.get( CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); @@ -722,10 +697,6 @@ public class Camera2RawFragment extends Fragment Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)), new CompareSizesByArea()); - Size largestRaw = Collections.max( - Arrays.asList(map.getOutputSizes(ImageFormat.RAW_SENSOR)), - new CompareSizesByArea()); - synchronized (mCameraStateLock) { // Set up ImageReaders for JPEG and RAW outputs. Place these in a reference // counted wrapper to ensure they are only closed when all background tasks @@ -738,14 +709,6 @@ public class Camera2RawFragment extends Fragment mJpegImageReader.get().setOnImageAvailableListener( mOnJpegImageAvailableListener, mBackgroundHandler); - if (mRawImageReader == null || mRawImageReader.getAndRetain() == null) { - mRawImageReader = new RefCountedAutoCloseable<>( - ImageReader.newInstance(largestRaw.getWidth(), - largestRaw.getHeight(), ImageFormat.RAW_SENSOR, /*maxImages*/ 5)); - } - mRawImageReader.get().setOnImageAvailableListener( - mOnRawImageAvailableListener, mBackgroundHandler); - mCharacteristics = characteristics; mCameraId = cameraId; } @@ -875,10 +838,6 @@ public class Camera2RawFragment extends Fragment mJpegImageReader.close(); mJpegImageReader = null; } - if (null != mRawImageReader) { - mRawImageReader.close(); - mRawImageReader = null; - } } } catch (InterruptedException e) { throw new RuntimeException("Interrupted while trying to lock camera closing.", e); @@ -935,8 +894,7 @@ public class Camera2RawFragment extends Fragment // Here, we create a CameraCaptureSession for camera preview. mCameraDevice.createCaptureSession(Arrays.asList(surface, - mJpegImageReader.get().getSurface(), - mRawImageReader.get().getSurface()), new CameraCaptureSession.StateCallback() { + mJpegImageReader.get().getSurface()), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession cameraCaptureSession) { synchronized (mCameraStateLock) { @@ -1047,8 +1005,11 @@ public class Camera2RawFragment extends Fragment CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); // For still image captures, we always use the largest available size. - Size largestJpeg = Collections.max(Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)), - new CompareSizesByArea()); + Size[] resolutions = map.getHighResolutionOutputSizes(ImageFormat.JPEG); + if (resolutions == null) { + resolutions = map.getOutputSizes(ImageFormat.JPEG); + } + Size largestJpeg = Collections.max(Arrays.asList(resolutions), new CompareSizesByArea()); // Find the rotation of the device relative to the native device orientation. int deviceRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); @@ -1215,7 +1176,6 @@ public class Camera2RawFragment extends Fragment mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); captureBuilder.addTarget(mJpegImageReader.get().getSurface()); - captureBuilder.addTarget(mRawImageReader.get().getSurface()); // Use the same AE and AF modes as the preview. setup3AControlsLocked(captureBuilder); @@ -1238,7 +1198,6 @@ public class Camera2RawFragment extends Fragment .setCharacteristics(mCharacteristics); mJpegResultQueue.put((int) request.getTag(), jpegBuilder); - mRawResultQueue.put((int) request.getTag(), rawBuilder); mCaptureSession.capture(request, mCaptureCallback, mBackgroundHandler); diff --git a/Application/src/main/java/com/example/android/camera2raw/CameraActivity.java b/Application/src/main/java/com/xypower/mppreview/CameraActivity.java similarity index 96% rename from Application/src/main/java/com/example/android/camera2raw/CameraActivity.java rename to Application/src/main/java/com/xypower/mppreview/CameraActivity.java index e56efab..b1d7d1c 100644 --- a/Application/src/main/java/com/example/android/camera2raw/CameraActivity.java +++ b/Application/src/main/java/com/xypower/mppreview/CameraActivity.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.example.android.camera2raw; +package com.xypower.mppreview; import android.app.Activity; import android.os.Bundle; diff --git a/Application/src/main/res/layout-land/fragment_camera2_basic.xml b/Application/src/main/res/layout-land/fragment_camera2_basic.xml index 3881adf..e2747b9 100644 --- a/Application/src/main/res/layout-land/fragment_camera2_basic.xml +++ b/Application/src/main/res/layout-land/fragment_camera2_basic.xml @@ -17,15 +17,15 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_alignParentTop="true" + android:layout_alignParentBottom="true" /> - + android:background="#504285f4" + android:orientation="vertical">