Android 12 - 部分相机横屏显示方案

1.相机过渡界面方向旋转

Android 10 - 相机过渡界面默认角度

同A10 有些区别,再次增加记录修改。

复制代码
这个文件没有修改,只是说明
src/com/android/camera/CameraActivity.java

    private void freezeScreenCommon(boolean async) {
        long startTime = System.currentTimeMillis();
        mCameraAppUI.setModeCoverState(1);
        mStartTime = startTime;
        if (mCurrentModule.isUseSurfaceView()) {
            Bitmap screenShot = getSurfaceViewBitmap();
            if (screenShot == null) {
                freezeScreenUntilPreviewReady();//SPRD:fix bug1116034
            } else {
                //CameraUtil.saveBitmapToFile(screenShot);
                // 经过注释验证,将下面的两个方法注释,就不会显示过渡画面
                screenShot = CameraUtil.blurBitmap(CameraUtil.computeScale(screenShot, 0.2f), mAppContext);
                mCameraAppUI.freezeScreenUntilPreviewReady(screenShot, async);
            }
        } else {
            freezeScreenUntilPreviewReady(async);
        }
        Log.i(TAG, "freezeScreenCommon cost: " + (System.currentTimeMillis() - startTime));
    }

src/com/android/camera/util/CameraUtil.java

// 旋转 Bitmap 的辅助方法
private static Bitmap rotateBitmap(Bitmap source, float angle) {
    if (source == null) {
        return null;
    }
    Log.d(TAG, "Original width: " + source.getWidth() + ", height: " + source.getHeight());
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    Bitmap rotatedBitmap = Bitmap.createBitmap(
        source,
        0, 0,
        source.getWidth(),
        source.getHeight(),
        matrix,
        true
    );
    // 打印旋转后图片宽高
    Log.d(TAG, "Rotated width: " + rotatedBitmap.getWidth() + ", height: " + rotatedBitmap.getHeight());
    return rotatedBitmap;
}

    public static Bitmap blurBitmap(Bitmap bitmap, Context context) {
        if (bitmap == null) {
            return null;
        }
        long startMs = System.currentTimeMillis();

        // 这里是新增加的方法,实现过渡画面的角度,当前项目旋转90度即可
        bitmap = rotateBitmap(bitmap, 90);
        // Instantiate a new Renderscript
        RenderScript rs = RenderScript.create(context);

src/com/android/camera/app/CameraAppUI.java


    public void freezeScreenUntilPreviewReady(Bitmap bitmap, boolean async) {
        Log.v(TAG, "freezeScreenUntilPreviewReady bitmap=" + bitmap + "; async=" + async + " getPreviewArea :" + getPreviewAreaLocal());
        // lichang 修改原有获取预览区域方法为自行获取,原尺寸异常
        freezeScreen(bitmap, getPreviewAreaLocal(), async);
    }

    /**
     * 根据宽高比获取预览区域
     */
    public RectF getPreviewAreaLocal() {
        Log.v(TAG, "getPreviewAreaLocal getAspectRation() = " + getAspectRation());
        float previewWidth = 960f;
        float screenWidth = 1280f;
        float aspectRation = getAspectRation();
        float epsilon = 0.001f; // 允许的误差范围
        if (Math.abs(aspectRation - (4f / 3f)) < epsilon) {
            // 4:3 比例(≈1.333)
            previewWidth = 960f;
        } else if (Math.abs(aspectRation - (16f / 9f)) < epsilon) {
            // 16:9 比例(≈1.777)
            previewWidth = 1280f;
        } else {
            // 其他比例,默认值或错误处理
            previewWidth = 1280f; // 或 throw new IllegalArgumentException("Unsupported aspect ratio");
        }
        float left = (screenWidth - previewWidth) / 2f;
        Log.v(TAG, "getPreviewAreaLocal left = " + left + " right = " + left + previewWidth);
        return new RectF(left, 0f, left + previewWidth, 720f);
    }

    // 新增方法
    public float getAspectRation() {
        return mTextureViewHelper.getAspectRation();
    }

src/com/android/camera/TextureViewHelper.java

    public void setAspectRation(float aspectRation) {
        mAspectRatio = aspectRation;
    }

    // 新增方法,获取当前宽高比
    public float getAspectRation() {
        return mAspectRatio;
    }

2.相机图标位置居中

复制代码
+++ b/src/com/android/camera/ui/ModeTransitionView.java
@@ -143,6 +143,7 @@ public class ModeTransitionView extends View {
                     mIconDrawable.setAlpha(alpha);
                 }
             }
+           Log.e(TAG, " updateShade mWidth = " + mWidth + " mHeight = " + mHeight);
             invalidate();
         }
     }
@@ -172,6 +173,7 @@ public class ModeTransitionView extends View {
 
     @Override
     public void onDraw(Canvas canvas) {
+       Log.e(TAG, " lichang  onDraw ");
         if (mAnimationType == PEEP_HOLE_ANIMATION) {
             canvas.drawColor(mBackgroundColor);
             if (mPeepHoleAnimator != null) {
@@ -227,8 +229,9 @@ public class ModeTransitionView extends View {
         mWidth = displaySize.getWidth();
         mHeight = displaySize.getHeight();
         boolean landscape = mWidth > mHeight;
-        int centerW = landscape ? mHeight : mWidth;
-        int centerH = landscape ? mWidth : mHeight;
+       // lichang 横屏也不需要调换位置,修改打开相机显示的图标位置
+        int centerW = !landscape ? mHeight : mWidth;
+        int centerH = !landscape ? mWidth : mHeight;
         if (CameraUtil.hasCutout()) {
             centerH -= CameraUtil.getCutoutHeight();

3.预览画面居中

默认4:3,显示的预览画面偏移,需要重新计算位置。

复制代码
+++ b/src/com/android/camera/SurfaceViewEx.java
@@ -19,6 +19,8 @@
 
 package com.android.camera;
 
+import android.util.DisplayMetrics;
+import android.view.WindowManager;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -165,8 +167,16 @@ public class SurfaceViewEx extends SurfaceView {
                     params.height = (int) scaledTextureHeight;
                     RectF rect = mCameraAppUI.getPreviewArea();
                     // horizontal direction
-                    params.setMargins((int) rect.left, (int) rect.top, 0, 0);
-
+                    //params.setMargins((int) rect.left, (int) rect.top, 0, 0);
+                   // lichang 将预览画面居中
+                   /*@start*/
+                   DisplayMetrics displayMetrics = new DisplayMetrics();
+                    ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displayMetrics);
+                    int screenWidth = displayMetrics.widthPixels;
+                    int screenHeight = displayMetrics.heightPixels;
+                    Log.i(TAG, "setTransformMatrix(): screenWidth = " + screenWidth + " screenHeight = " + screenHeight);
+                   params.setMargins((int) (screenWidth - scaledTextureWidth) / 2, (int) (screenHeight - scaledTextureHeight) / 2, 0, 0);
+                   /*end*/
                     setLayoutParams(params);
 
                     Log.i(TAG, "setTransformMatrix(): width = " + previewWidth
相关推荐
小李飞飞砖4 小时前
Sophix、Tinker 和 Robust 三大主流 Android 热修复框架的详细对比
android
人生游戏牛马NPC1号7 小时前
学习 Flutter (一)
android·学习·flutter
fundroid8 小时前
Swift 进军 Android,Kotlin 该如何应对?
android·ios
前端世界8 小时前
鸿蒙系统安全机制全解:安全启动 + 沙箱 + 动态权限实战落地指南
android·安全·harmonyos
_一条咸鱼_10 小时前
Vulkan入门教程:源码级解析
android·面试·android jetpack
嘉小华10 小时前
ThreadLocal 详解
android
wkj00111 小时前
php 如何通过mysqli操作数据库?
android·数据库·php
kymjs张涛13 小时前
零一开源|前沿技术周报 #7
android·前端·ios
wuwu_q14 小时前
RK3566/RK3568 Android11 修改selinux模式
android·rk3568