1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.camera.core.impl.utils; 18 19 import android.view.Surface; 20 21 import androidx.camera.core.Logger; 22 import androidx.camera.core.impl.ImageOutputConfig.RotationValue; 23 24 /** 25 * Contains utility methods related to camera orientation. 26 */ 27 public final class CameraOrientationUtil { 28 private static final String TAG = "CameraOrientationUtil"; 29 30 // Do not allow instantiation CameraOrientationUtil()31 private CameraOrientationUtil() { 32 } 33 34 /** 35 * Calculates the delta between a source rotation and destination rotation. 36 * 37 * <p>A typical use of this method would be calculating the angular difference between the 38 * display orientation (destRotationDegrees) and camera sensor orientation 39 * (sourceRotationDegrees). 40 * 41 * @param destRotationDegrees The destination rotation relative to the device's natural 42 * rotation. 43 * @param sourceRotationDegrees The source rotation relative to the device's natural rotation. 44 * @param isOppositeFacing Whether the source and destination planes are facing opposite 45 * directions. 46 */ getRelativeImageRotation( int destRotationDegrees, int sourceRotationDegrees, boolean isOppositeFacing)47 public static int getRelativeImageRotation( 48 int destRotationDegrees, int sourceRotationDegrees, boolean isOppositeFacing) { 49 int result; 50 if (isOppositeFacing) { 51 result = (sourceRotationDegrees - destRotationDegrees + 360) % 360; 52 } else { 53 result = (sourceRotationDegrees + destRotationDegrees) % 360; 54 } 55 if (Logger.isVerboseEnabled(TAG)) { 56 Logger.d( 57 TAG, 58 String.format( 59 "getRelativeImageRotation: destRotationDegrees=%s, " 60 + "sourceRotationDegrees=%s, isOppositeFacing=%s, " 61 + "result=%s", 62 destRotationDegrees, sourceRotationDegrees, isOppositeFacing, result)); 63 } 64 return result; 65 } 66 67 /** 68 * Converts rotation constant values defined in {@link Surface} to their equivalent in 69 * degrees. 70 * 71 * <p>Valid values for the relative rotation are {@link Surface#ROTATION_0}, {@link 72 * Surface#ROTATION_90}, {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}. 73 * 74 * @param rotation One of the rotation constant values from {@link Surface}. 75 * @return The equivalent rotation value in degrees. 76 * @throws IllegalArgumentException If the provided rotation value is not one of those 77 * defined in {@link Surface}. 78 */ surfaceRotationToDegrees(@otationValue int rotation)79 public static int surfaceRotationToDegrees(@RotationValue int rotation) { 80 int rotationDegrees; 81 switch (rotation) { 82 case Surface.ROTATION_0: 83 rotationDegrees = 0; 84 break; 85 case Surface.ROTATION_90: 86 rotationDegrees = 90; 87 break; 88 case Surface.ROTATION_180: 89 rotationDegrees = 180; 90 break; 91 case Surface.ROTATION_270: 92 rotationDegrees = 270; 93 break; 94 default: 95 throw new IllegalArgumentException("Unsupported surface rotation: " + rotation); 96 } 97 98 return rotationDegrees; 99 } 100 101 /** 102 * Converts rotation degrees to their equivalent in values defined in {@link Surface}. 103 * 104 * <p>Valid values for the relative rotation are {@link Surface#ROTATION_0}, {@link 105 * Surface#ROTATION_90}, {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}. 106 * 107 * @param degrees The rotation value in degrees. 108 * @return One of the constant rotation values defined in {@link Surface}. 109 * @throws IllegalArgumentException If the provided rotation degrees doesn't fall into any 110 * one of those defined in {@link Surface}. 111 */ 112 @RotationValue degreesToSurfaceRotation(int degrees)113 public static int degreesToSurfaceRotation(int degrees) { 114 int surfaceRotation = Surface.ROTATION_0; 115 switch (degrees) { 116 case 0: 117 surfaceRotation = Surface.ROTATION_0; 118 break; 119 case 90: 120 surfaceRotation = Surface.ROTATION_90; 121 break; 122 case 180: 123 surfaceRotation = Surface.ROTATION_180; 124 break; 125 case 270: 126 surfaceRotation = Surface.ROTATION_270; 127 break; 128 default: 129 throw new IllegalStateException("Invalid sensor rotation: " + degrees); 130 } 131 132 return surfaceRotation; 133 } 134 } 135