春秋墨迹 發表於 2021-1-13 17:34:00

Android Camera开发系列:调整Camera预览方向

<p>有时候我们想根据自己的需要调整下Camera的预览方向,那么是调用哪个API可以达到我们的目的呢?</p>
<p>我们看下下图拍的几张小可爱的照片,分别是正常方向、旋转180度、90度拍的照片。<br>
​<img src="https://upload-images.jianshu.io/upload_images/16344730-e128564ad393c519?imageMogr2/auto-orient/strip%7CimageView2/2/w/200"></p>
<p><img src="https://upload-images.jianshu.io/upload_images/16344730-a4cabb6fb3a4dbd4?imageMogr2/auto-orient/strip%7CimageView2/2/w/200"></p>
<p><img src="https://upload-images.jianshu.io/upload_images/16344730-6e67716d589d9fd7?imageMogr2/auto-orient/strip%7CimageView2/2/w/200"></p>
<h3 id="一camera-api">一、Camera API</h3>
<p>Camera1上,我们可以通过<strong>setDisplayOrientation(int degress);</strong>来设置camera预览的方向。</p>
<pre><code>mCamera.setDisplayOrientation(Surface.ROTATION_180);
</code></pre>
<p>这里也贴下源码里面关于setDisplayOrientaion接口的详细说明。</p>
<pre><code> /**
   * Set the clockwise rotation of preview display in degrees. This affects
   * the preview frames and the picture displayed after snapshot. This method
   * is useful for portrait mode applications. Note that preview display of
   * front-facing cameras is flipped horizontally before the rotation, that
   * is, the image is reflected along the central vertical axis of the camera
   * sensor. So the users can see themselves as looking into a mirror.
   *
   * &lt;p&gt;This does not affect the order of byte array passed in {@link
   * PreviewCallback#onPreviewFrame}, JPEG pictures, or recorded videos. This
   * method is not allowed to be called during preview.
   *
   * &lt;p&gt;If you want to make the camera image show in the same orientation as
   * the display, you can use the following code.
   * &lt;pre&gt;
   * public static void setCameraDisplayOrientation(Activity activity,
   *         int cameraId, android.hardware.Camera camera) {
   *   android.hardware.Camera.CameraInfo info =
   *             new android.hardware.Camera.CameraInfo();
   *   android.hardware.Camera.getCameraInfo(cameraId, info);
   *   int rotation = activity.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);
   * }
   * &lt;/pre&gt;
   *
   * &lt;p&gt;Starting from API level 14, this method can be called when preview is
   * active.
   *
   * &lt;p&gt;&lt;b&gt;Note: &lt;/b&gt;Before API level 24, the default value for orientation is 0\. Starting in
   * API level 24, the default orientation will be such that applications in forced-landscape mode
   * will have correct preview orientation, which may be either a default of 0 or
   * 180\. Applications that operate in portrait mode or allow for changing orientation must still
   * call this method after each orientation change to ensure correct preview display in all
   * cases.&lt;/p&gt;
   *
   * @param degrees the angle that the picture will be rotated clockwise.
   *                Valid values are 0, 90, 180, and 270.
   * @throws RuntimeException if setting orientation fails; usually this would
   *    be because of a hardware or other low-level error, or because
   *    release() has been called on this Camera instance.
   * @see #setPreviewDisplay(SurfaceHolder)
   */
    public native final void setDisplayOrientation(int degrees);
</code></pre>
<h3 id="二camera2-api"><strong>二、Camera2 API</strong></h3>
<p>Camera2的API上,找了一通,发现并没有像Camera1上,可以通过类似的接口来设置预览方向,不过可以通过TextureView.setTransform(matrix);来通过调整textureView的显示来达到目的。</p>
<pre><code>public void openCamera(){
            CameraManager manager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
      try {
         ......
//调整预览画面显示方向
configureTextureViewTransform(mTextureView.getWidth(),mTextureView.getHeight());
            manager.openCamera(cameraId, mStateCallback, null);
         ......
      }
}

private void configureTextureViewTransform(int viewWidth, int viewHeight) {
      if (null == mTextureView) {
            return;
      }
      int rotation = 0 ;/*activity.getWindowManager().getDefaultDisplay().getRotation();*/
      Matrix matrix = new Matrix();
      RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
      RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
      float centerX = viewRect.centerX();
      float centerY = viewRect.centerY();
      if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
            float scale = Math.max(
                  (float) viewHeight / mPreviewSize.getHeight(),
                  (float) viewWidth / mPreviewSize.getWidth());
            matrix.postScale(scale, scale, centerX, centerY);
            matrix.postRotate(90 * (rotation - 2), centerX, centerY);
      }else if (Surface.ROTATION_180 == rotation) {
            matrix.postRotate(180, centerX, centerY);
      }
      mTextureView.setTransform(matrix);
    }
</code></pre>
<p>=======================================================================</p>
<h6 id="本人从事android-camera相关开发已有5年">*<em>本人从事Android Camera相关开发已有5年,</em></h6>
<h6 id="目前在深圳上班">*<em>目前在深圳上班,</em></h6>
<h6 id="小伙伴记得点我头像关注也可以关注我的微信公众号小驰笔记希望和更多的小伙伴一起交流-">*<em>小伙伴记得点我头像关注,也可以关注我的微信公众号【小驰笔记】,希望和更多的小伙伴一起交流 ~</em></h6>
<p><img src="https://img2020.cnblogs.com/blog/2279751/202101/2279751-20210113164428529-1663209907.png"></p><br><br>
来源:https://www.cnblogs.com/york-zhou/p/14273314.html
頁: [1]
查看完整版本: Android Camera开发系列:调整Camera预览方向