diff --git a/change.txt b/change.txt index bf738f604e..07a679c6a1 100644 --- a/change.txt +++ b/change.txt @@ -48,6 +48,8 @@ Version : Alpha 0.21 * Fixed issue were a strict non-maximum was used when a non-strict was needed causing valid lines to be discarded - WebcamCapture * Provided an easy to use function that allows you to open devices by their /dev name +- Android + * Will automatically detect if image needs to be rotated 180 degrees and then does it. Needed for the Nexus 5x - TODO Partial chessboard diff --git a/integration/android/src/boofcv/android/gui/VideoDisplayActivity.java b/integration/android/src/boofcv/android/gui/VideoDisplayActivity.java index 2ac11fece5..73612f98ef 100644 --- a/integration/android/src/boofcv/android/gui/VideoDisplayActivity.java +++ b/integration/android/src/boofcv/android/gui/VideoDisplayActivity.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved. + * + * This file is part of BoofCV (http://boofcv.org). + * + * 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 + * + * http://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 boofcv.android.gui; import android.app.Activity; @@ -7,11 +25,11 @@ import android.hardware.Camera; import android.os.Bundle; import android.os.Looper; +import android.view.Surface; import android.view.SurfaceView; import android.view.Window; import android.widget.FrameLayout; import android.widget.LinearLayout; - import android.widget.LinearLayout.LayoutParams; /** @@ -54,6 +72,9 @@ public abstract class VideoDisplayActivity extends Activity implements Camera.Pr LinearLayout contentView; FrameLayout preview; + // number of degrees the preview image neesd to be rotated + protected int previewRotation; + public VideoDisplayActivity() { } @@ -77,7 +98,7 @@ public void setProcessing( VideoProcessing processing ) { this.processing = processing; // if the camera is null then it will be initialized when the camera is initialized if( processing != null && mCamera != null ) { - processing.init(mDraw,mCamera,mCameraInfo); + processing.init(mDraw,mCamera,mCameraInfo,previewRotation); } } @@ -158,12 +179,13 @@ protected void onPause() { private void setUpAndConfigureCamera() { // Open and configure the camera mCamera = openConfigureCamera(mCameraInfo); + setCameraDisplayOrientation(mCameraInfo,mCamera); // Create an instance of Camera mPreview.setCamera(mCamera); if( processing != null ) { - processing.init(mDraw,mCamera,mCameraInfo); + processing.init(mDraw,mCamera,mCameraInfo,previewRotation); } } @@ -174,6 +196,31 @@ private void setUpAndConfigureCamera() { */ protected abstract Camera openConfigureCamera( Camera.CameraInfo cameraInfo); + public void setCameraDisplayOrientation(Camera.CameraInfo info, + Camera camera) { + + int rotation = this.getWindowManager().getDefaultDisplay() + .getRotation(); + int degrees = 0; + switch (rotation) { + case Surface.ROTATION_0: degrees = 0; break; + case Surface.ROTATION_90: degrees = 90; break; + case Surface.ROTATION_180: degrees = 180; break; + case Surface.ROTATION_270: degrees = 270; break; + } + + int result; + if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { + result = (info.orientation + degrees) % 360; + result = (360 - result) % 360; // compensate the mirror + } else { // back-facing + result = (info.orientation - degrees + 360) % 360; + } + camera.setDisplayOrientation(result); + + previewRotation = result; + } + @Override public void onPreviewFrame(byte[] bytes, Camera camera) { if( processing != null ) diff --git a/integration/android/src/boofcv/android/gui/VideoProcessing.java b/integration/android/src/boofcv/android/gui/VideoProcessing.java index 96eda1bedf..72b5badfda 100644 --- a/integration/android/src/boofcv/android/gui/VideoProcessing.java +++ b/integration/android/src/boofcv/android/gui/VideoProcessing.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved. + * + * This file is part of BoofCV (http://boofcv.org). + * + * 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 + * + * http://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 boofcv.android.gui; import android.graphics.Canvas; @@ -19,7 +37,7 @@ */ public interface VideoProcessing { - public void init( View view , Camera camera , Camera.CameraInfo info ); + public void init( View view , Camera camera , Camera.CameraInfo info , int rotation ); /** * Invoked by Android GUI thread. Should be run as fast as possible to avoid making the GUI feel sluggish. diff --git a/integration/android/src/boofcv/android/gui/VideoRenderProcessing.java b/integration/android/src/boofcv/android/gui/VideoRenderProcessing.java index ccf14f4957..b1e90c3d8b 100644 --- a/integration/android/src/boofcv/android/gui/VideoRenderProcessing.java +++ b/integration/android/src/boofcv/android/gui/VideoRenderProcessing.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015, Peter Abeles. All Rights Reserved. + * Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved. * * This file is part of BoofCV (http://boofcv.org). * @@ -82,17 +82,21 @@ public abstract class VideoRenderProcessing extends Thread // if true the input image is flipped horizontally boolean flipHorizontal; + // number of degrees the camera preview needs to be rotated + int previewRotation; + protected VideoRenderProcessing(ImageType imageType) { this.imageType = imageType; } @Override - public void init(View view, Camera camera , Camera.CameraInfo info ) { + public void init(View view, Camera camera , Camera.CameraInfo info , int previewRotation ) { synchronized (lockGui) { this.view = view; // Front facing cameras need to be flipped to appear correctly flipHorizontal = info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT; + this.previewRotation = previewRotation; Camera.Size size = camera.getParameters().getPreviewSize(); outputWidth = size.width; outputHeight = size.height; @@ -172,7 +176,14 @@ else if( imageType.getDataType() == ImageDataType.F32) throw new RuntimeException("Unexpected image type: "+imageType); } - if( flipHorizontal ) + if( previewRotation == 180 ) { + if( flipHorizontal ) { + GImageMiscOps.flipVertical(image); + } else { + GImageMiscOps.flipVertical(image); + GImageMiscOps.flipHorizontal(image); + } + } else if( flipHorizontal ) GImageMiscOps.flipHorizontal(image); } // wake up the thread and tell it to do some processing