web-dev-qa-db-ja.com

android textureviewフルスクリーンプレビューと正しいアスペクト比

私は googleのcamera2 api demo で作業してきましたが、残念ながら、サンプルアプリケーションは、画面の高さの約70%でtextureviewプレビューを表示するように構築されています。周りを見回した後、これが以下に示すように、AutoFitTextureViewがonMeasure()メソッドをオーバーライドすることが原因です。

_@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);
    if (0 == mRatioWidth || 0 == mRatioHeight) {
        setMeasuredDimension(width, height);
    } else {
        if (width < height * mRatioWidth / mRatioHeight) {
            setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
        } else {
            setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
        }
    }
}
_

setMeasuredDimension(width, height);で正しい高さと幅を設定してこれを修正しようとしました。これにより、高さの問題が修正され、textureviewから全画面プレビューが表示されましたが、すべてのデバイスでアスペクト比が完全に壊れて歪んでいます。これを修正する標準的な方法は何ですか? Playストアの多くのアプリがこの問題を解決する方法を見つけましたが、修正を追跡することができませんでした。助けがあれば大いに役立ちます。

13
Edmund Rojas

SetMeasuredDimension();を切り替えることで問題を修正できました。

    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);
    if (0 == mRatioWidth || 0 == mRatioHeight) {
        setMeasuredDimension(width, height);
    } else {
        if (width < height * mRatioWidth / mRatioHeight) {
            setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
        } else {
            setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
        }
    }
17
Edmund Rojas

4:3、16:9、および1:1のプレビューサイズをサポートするプレビューを測定するために使用したコードを以下に示します。アプリは縦向きでブロックされているため、高さはスケーリングされ、横向きには回転しません。

それがあなたや同じ問題を抱えている他の誰かに役立つことを願っています!

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);

    Log.d(TAG, "[onMeasure] Before transforming: " + width + "x" + height);

    int rotation = ((Activity) getContext()).getWindowManager().getDefaultDisplay().getRotation();
    boolean isInHorizontal = Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation;

    int newWidth;
    int newHeight;

    Log.d(TAG, "[onMeasure] Get measured dimensions: " + getMeasuredWidth() + "x" + getMeasuredHeight());

    if (isInHorizontal) {
        newHeight = getMeasuredHeight();
        if (mAspectRatioOneOne) newWidth = getMeasuredHeight();
        else newWidth = (int) (newHeight * mAspectRatio);
    } else {
        newWidth = getMeasuredWidth();
        if (mAspectRatioOneOne) newHeight = getMeasuredWidth();
        else newHeight = (int) (newWidth * mAspectRatio);
    }

    setMeasuredDimension(newWidth, newHeight);
    Log.d(TAG, "[onMeasure] After transforming: " + getMeasuredWidth() + "x" + getMeasuredHeight());

}

Camera2の実装を使用しても同様の問題が発生しました。 TextureViewのAutoFitTextureView実装をカメラからのプレビューとして使用し、正しい比率に調整したいと思います。私の問題は、メソッドのさまざまな実装から得られ、onSurfaceTextureSizeChangedに伝播します。 [1] com.google.Android.cameraview.CameraView#onMeasure(..)-> [2] com.google.Android.cameraview.AutoFitTextureView#onMeasure(..)-> [3] onSurfaceTextureSizeChanged(..)

どこが違うのか もし [2]よりも[1]。 [1]で置き換えました:

if (height < width * ratio.getY() / ratio.getX()) {

if (!(height < width * ratio.getY() / ratio.getX())) {

[2]は高さではなく幅に基づいている場合

 if (width < height * mRatioWidth / mRatioHeight) {

メソッドonMeasure(..)が正しく実装されているかどうかを確認します。

または、EdmundRojasのようにすることもできます-上記

1
Damian JK

フルスクリーンで歪みのないプレビューが必要な場合は、画面のアスペクト比に一致するカメラのプレビュー解像度を選択する必要があります。

ただし、画面サイズが標準サイズ(基本的に16:9または4:3)でない場合、特にソフトボタンと通知バーを差し引くと(完全にフルスクリーンではないと仮定して)、唯一のプレビューを画面全体に表示するためのオプションは、プレビューの一部を切り取ることです。

ビューの幅と高さ、および選択したプレビューの幅と高さを確認することで、TextureViewの変換行列を変更して歪みを取り除くことができるはずですが、これにより、必然的に一部が切り取られます。

0
Eddy Talvala