diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java index f5140eb2b..1ab80b374 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java @@ -1,5 +1,10 @@ package com.otaliastudios.cameraview; +import static android.view.View.MeasureSpec.AT_MOST; +import static android.view.View.MeasureSpec.EXACTLY; +import static android.view.View.MeasureSpec.UNSPECIFIED; +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; + import android.Manifest; import android.annotation.SuppressLint; import android.annotation.TargetApi; @@ -66,8 +71,8 @@ import com.otaliastudios.cameraview.gesture.PinchGestureFinder; import com.otaliastudios.cameraview.gesture.ScrollGestureFinder; import com.otaliastudios.cameraview.gesture.TapGestureFinder; -import com.otaliastudios.cameraview.internal.GridLinesLayout; import com.otaliastudios.cameraview.internal.CropHelper; +import com.otaliastudios.cameraview.internal.GridLinesLayout; import com.otaliastudios.cameraview.internal.OrientationHelper; import com.otaliastudios.cameraview.markers.AutoFocusMarker; import com.otaliastudios.cameraview.markers.AutoFocusTrigger; @@ -99,11 +104,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import static android.view.View.MeasureSpec.AT_MOST; -import static android.view.View.MeasureSpec.EXACTLY; -import static android.view.View.MeasureSpec.UNSPECIFIED; -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; - /** * Entry point for the whole library. * Please read documentation for usage and full set of features. @@ -2742,5 +2742,8 @@ public Filter getFilter() { } + public void reloadDisplayOrientation() { + mCameraEngine.reloadDisplayOrientation(); + } //endregion } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CustomConstants.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CustomConstants.java new file mode 100644 index 000000000..a324ce9be --- /dev/null +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CustomConstants.java @@ -0,0 +1,10 @@ +package com.otaliastudios.cameraview; + +public class CustomConstants { + + //前后置摄像头的偏移角度,为了解决部分终端摄像头旋转角度不对的问题 + public static int front_media_camera_rotate = -1; + public static int back_media_camera_rotate = -1; + public static boolean front_media_camera_reverse_width_height = false; + public static boolean back_media_camera_reverse_width_height = false; +} diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/controls/Facing.java b/cameraview/src/main/java/com/otaliastudios/cameraview/controls/Facing.java index 90684b11e..af3830f78 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/controls/Facing.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/controls/Facing.java @@ -24,7 +24,9 @@ public enum Facing implements Control { /** * Front-facing camera sensor. */ - FRONT(1); + FRONT(1), + + RED(3); @NonNull static Facing DEFAULT(@Nullable Context context) { diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java index 6f976f089..e7dec58ff 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java @@ -9,17 +9,25 @@ import android.hardware.Camera; import android.location.Location; import android.os.Build; +import android.view.SurfaceHolder; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; -import android.view.SurfaceHolder; - import com.google.android.gms.tasks.Task; import com.google.android.gms.tasks.Tasks; import com.otaliastudios.cameraview.CameraException; import com.otaliastudios.cameraview.CameraOptions; +import com.otaliastudios.cameraview.CustomConstants; +import com.otaliastudios.cameraview.PictureResult; +import com.otaliastudios.cameraview.VideoResult; +import com.otaliastudios.cameraview.controls.Facing; +import com.otaliastudios.cameraview.controls.Flash; +import com.otaliastudios.cameraview.controls.Hdr; +import com.otaliastudios.cameraview.controls.Mode; import com.otaliastudios.cameraview.controls.PictureFormat; +import com.otaliastudios.cameraview.controls.WhiteBalance; import com.otaliastudios.cameraview.engine.mappers.Camera1Mapper; import com.otaliastudios.cameraview.engine.metering.Camera1MeteringTransform; import com.otaliastudios.cameraview.engine.offset.Axis; @@ -28,15 +36,8 @@ import com.otaliastudios.cameraview.engine.orchestrator.CameraState; import com.otaliastudios.cameraview.frame.ByteBufferFrameManager; import com.otaliastudios.cameraview.frame.Frame; -import com.otaliastudios.cameraview.PictureResult; -import com.otaliastudios.cameraview.VideoResult; -import com.otaliastudios.cameraview.controls.Facing; -import com.otaliastudios.cameraview.controls.Flash; import com.otaliastudios.cameraview.frame.FrameManager; import com.otaliastudios.cameraview.gesture.Gesture; -import com.otaliastudios.cameraview.controls.Hdr; -import com.otaliastudios.cameraview.controls.Mode; -import com.otaliastudios.cameraview.controls.WhiteBalance; import com.otaliastudios.cameraview.internal.CropHelper; import com.otaliastudios.cameraview.metering.MeteringRegions; import com.otaliastudios.cameraview.metering.MeteringTransform; @@ -140,6 +141,10 @@ protected boolean collectCameraInfo(@NonNull Facing facing) { "Internal:", internalFacing, "Cameras:", Camera.getNumberOfCameras()); Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); + if (internalFacing == 3) { + mCameraId = 3; + return true; + } for (int i = 0, count = Camera.getNumberOfCameras(); i < count; i++) { Camera.getCameraInfo(i, cameraInfo); if (cameraInfo.facing == internalFacing) { @@ -184,8 +189,15 @@ protected Task onStartEngine() { throw new CameraException(e, CameraException.REASON_FAILED_TO_CONNECT); } try { - mCamera.setDisplayOrientation(getAngles().offset(Reference.SENSOR, Reference.VIEW, - Axis.ABSOLUTE)); // <- not allowed during preview + // <- not allowed during preview + int offset = getAngles().offset(Reference.SENSOR, Reference.VIEW, Axis.ABSOLUTE); + int front_media_camera_rotate = CustomConstants.front_media_camera_rotate; + int back_media_camera_rotate = CustomConstants.back_media_camera_rotate; + if(getFacing() == Facing.BACK){ + mCamera.setDisplayOrientation(back_media_camera_rotate >= 0 ? back_media_camera_rotate : offset); + }else{ + mCamera.setDisplayOrientation(front_media_camera_rotate >= 0 ? front_media_camera_rotate : offset); + } } catch (Exception e) { LOG.e("onStartEngine:", "Failed to connect. Can't set display orientation, maybe preview already exists?"); throw new CameraException(CameraException.REASON_FAILED_TO_CONNECT); @@ -194,6 +206,19 @@ protected Task onStartEngine() { return Tasks.forResult(mCameraOptions); } + @Override + public void reloadDisplayOrientation() { + if (null == mCamera) return; + int offset = getAngles().offset(Reference.SENSOR, Reference.VIEW, Axis.ABSOLUTE); + int front_media_camera_rotate = CustomConstants.front_media_camera_rotate; + int back_media_camera_rotate = CustomConstants.back_media_camera_rotate; + if(getFacing() == Facing.BACK){ + mCamera.setDisplayOrientation(back_media_camera_rotate >= 0 ? back_media_camera_rotate : offset); + }else{ + mCamera.setDisplayOrientation(front_media_camera_rotate >= 0 ? front_media_camera_rotate : offset); + } + } + @EngineThread @NonNull @Override @@ -229,7 +254,20 @@ protected Task onStartPreview() { if (previewSize == null) { throw new IllegalStateException("previewStreamSize should not be null at this point."); } - mPreview.setStreamSize(previewSize.getWidth(), previewSize.getHeight()); + + if (this.getFacing() == Facing.BACK) { + if(CustomConstants.back_media_camera_reverse_width_height){ + this.mPreview.setStreamSize(previewSize.getHeight(), previewSize.getWidth()); + }else{ + this.mPreview.setStreamSize(previewSize.getWidth(), previewSize.getHeight()); + } + } else { + if(CustomConstants.front_media_camera_reverse_width_height){ + this.mPreview.setStreamSize(previewSize.getHeight(), previewSize.getWidth()); + }else{ + this.mPreview.setStreamSize(previewSize.getWidth(), previewSize.getHeight()); + } + } mPreview.setDrawRotation(0); Camera.Parameters params; diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java index a8d2fd631..37194772b 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java @@ -470,6 +470,8 @@ public void onError(@NonNull CameraDevice camera, int error) { return task.getTask(); } + + @EngineThread @NonNull @Override @@ -1361,6 +1363,11 @@ public void setPlaySounds(boolean playSounds) { mPlaySoundsTask = Tasks.forResult(null); } + @Override + public void reloadDisplayOrientation() { + + } + @Override public void setPreviewFrameRate(float previewFrameRate) { final float oldPreviewFrameRate = mPreviewFrameRate; diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java index 0614789dc..ddd7acda6 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java @@ -3,11 +3,13 @@ import android.content.Context; import android.graphics.PointF; import android.location.Location; - - import android.os.Handler; import android.os.Looper; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; + import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.OnSuccessListener; import com.google.android.gms.tasks.SuccessContinuation; @@ -17,37 +19,33 @@ import com.otaliastudios.cameraview.CameraLogger; import com.otaliastudios.cameraview.CameraOptions; import com.otaliastudios.cameraview.PictureResult; +import com.otaliastudios.cameraview.VideoResult; +import com.otaliastudios.cameraview.controls.Audio; import com.otaliastudios.cameraview.controls.AudioCodec; +import com.otaliastudios.cameraview.controls.Facing; +import com.otaliastudios.cameraview.controls.Flash; +import com.otaliastudios.cameraview.controls.Hdr; +import com.otaliastudios.cameraview.controls.Mode; import com.otaliastudios.cameraview.controls.PictureFormat; +import com.otaliastudios.cameraview.controls.VideoCodec; +import com.otaliastudios.cameraview.controls.WhiteBalance; +import com.otaliastudios.cameraview.engine.offset.Angles; +import com.otaliastudios.cameraview.engine.offset.Reference; import com.otaliastudios.cameraview.engine.orchestrator.CameraOrchestrator; import com.otaliastudios.cameraview.engine.orchestrator.CameraState; import com.otaliastudios.cameraview.engine.orchestrator.CameraStateOrchestrator; -import com.otaliastudios.cameraview.metering.MeteringRegions; -import com.otaliastudios.cameraview.overlay.Overlay; -import com.otaliastudios.cameraview.VideoResult; -import com.otaliastudios.cameraview.engine.offset.Angles; -import com.otaliastudios.cameraview.engine.offset.Reference; import com.otaliastudios.cameraview.frame.Frame; import com.otaliastudios.cameraview.frame.FrameManager; +import com.otaliastudios.cameraview.gesture.Gesture; import com.otaliastudios.cameraview.internal.WorkerHandler; +import com.otaliastudios.cameraview.metering.MeteringRegions; +import com.otaliastudios.cameraview.overlay.Overlay; import com.otaliastudios.cameraview.picture.PictureRecorder; import com.otaliastudios.cameraview.preview.CameraPreview; -import com.otaliastudios.cameraview.controls.Audio; -import com.otaliastudios.cameraview.controls.Facing; -import com.otaliastudios.cameraview.controls.Flash; -import com.otaliastudios.cameraview.gesture.Gesture; -import com.otaliastudios.cameraview.controls.Hdr; -import com.otaliastudios.cameraview.controls.Mode; -import com.otaliastudios.cameraview.controls.VideoCodec; -import com.otaliastudios.cameraview.controls.WhiteBalance; import com.otaliastudios.cameraview.size.Size; import com.otaliastudios.cameraview.size.SizeSelector; import com.otaliastudios.cameraview.video.VideoRecorder; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; - import java.io.File; import java.io.FileDescriptor; import java.util.concurrent.Callable; @@ -104,7 +102,7 @@ * * For convenience, the two main method {@link #onStartEngine()} and {@link #onStopEngine()} * are already called on the engine thread, but they can still be asynchronous by returning a - * Google's {@link com.google.android.gms.tasks.Task}. + * Google's {@link Task}. */ public abstract class CameraEngine implements CameraPreview.SurfaceCallback, @@ -376,6 +374,7 @@ protected Task restartPreview() { //region Start & Stop the engine + @NonNull @EngineThread private Task startEngine() { @@ -723,6 +722,6 @@ public abstract void takeVideo(@NonNull VideoResult.Stub stub, @Nullable FileDescriptor fileDescriptor); public abstract void takeVideoSnapshot(@NonNull VideoResult.Stub stub, @NonNull File file); public abstract void stopVideo(); - + public abstract void reloadDisplayOrientation(); //endregion } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/mappers/Camera1Mapper.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/mappers/Camera1Mapper.java index 95f288b40..6594d06b4 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/mappers/Camera1Mapper.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/mappers/Camera1Mapper.java @@ -42,6 +42,7 @@ public static Camera1Mapper get() { FLASH.put(Flash.TORCH, Camera.Parameters.FLASH_MODE_TORCH); FACING.put(Facing.BACK, Camera.CameraInfo.CAMERA_FACING_BACK); FACING.put(Facing.FRONT, Camera.CameraInfo.CAMERA_FACING_FRONT); + FACING.put(Facing.RED, 3); WB.put(WhiteBalance.AUTO, Camera.Parameters.WHITE_BALANCE_AUTO); WB.put(WhiteBalance.INCANDESCENT, Camera.Parameters.WHITE_BALANCE_INCANDESCENT); WB.put(WhiteBalance.FLUORESCENT, Camera.Parameters.WHITE_BALANCE_FLUORESCENT); diff --git a/demo/src/main/res/layout/activity_camera.xml b/demo/src/main/res/layout/activity_camera.xml index 2cc1d8a5a..9e7fe268e 100644 --- a/demo/src/main/res/layout/activity_camera.xml +++ b/demo/src/main/res/layout/activity_camera.xml @@ -16,7 +16,7 @@ android:layout_marginBottom="88dp" android:keepScreenOn="true" app:cameraExperimental="true" - app:cameraEngine="camera2" + app:cameraEngine="camera1" app:cameraPreview="glSurface" app:cameraPlaySounds="true" app:cameraGrid="off"