Как получить и обрабатывать размер поверхности в Android для предварительного просмотра камеры? - PullRequest
0 голосов
/ 02 октября 2019

Я пытаюсь показать предварительный просмотр в устройстве Android (API 19) на SurfaceView. Я могу получить доступ к CameraPReviews и выбрать один. Как вы, наверное, знаете, обычно camerapreviews не подходит для поверхностей. Как я обычно вижу, люди пытаются выбрать лучший предварительный просмотр, который соответствует виду поверхности. Я пробую новый подход, который изменяет вид поверхности в соответствии с форматным соотношением cameraPreviews. так что для этого я провел небольшой эксперимент, и результаты были хороши.

НО ... в обратном вызове SurfaceView существуют методы обратного вызова, созданные с поверхности и поверхности. И чтобы сделать расчеты, мне нужно знать ширину и высоту поверхности. Размеры поверхности обновляются в методе surfaceChanged. поэтому я использую эти значения для определения размеров поверхности. проблема в том, что SurfaceCreated работает «до» SurfaceChanged, так что мне нужно подождать, пока поверхность не изменится. сейчас я использую две логические переменные-члены. и вызывая стартовую камеру в обоих методах. Есть ли лучший способ сделать это? это может быть совершенно другой подход или другое решение этой конкретной проблемы «обработки обратного вызова»?

ps: я просто не могу рассчитывать на то, что изменилась поверхность, чтобы запустить камеру, потому что ее вызывают слишком много.

Основная активность и OnCreate

public class MainActivity extends AppCompatActivity {
    SurfaceView mainactivity_surfaceview;
    CameraSource cameraSource;
    BarcodeDetector barcodeDetector;
    int surfaceWidth;
    int surfaceHeight;
    boolean surfaceCreatedWorked = false;
    boolean surfaceChangedWorked = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // define elements
        mainactivity_surfaceview = findViewById(R.id.mainactivity_surfaceview);

        mainactivity_surfaceview.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                System.out.println("surfaceCreated ÇALIŞTI");
                surfaceCreatedWorked = true;
                startCamera("surfaceCreated");
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                System.out.println("surfaceChanged ÇALIŞTI");
                surfaceChangedWorked = true;
                surfaceWidth = width;
                surfaceHeight = height;
                startCamera("surfaceChanged");
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {

            }
        });
    }
...
...
...

}

Метод StartCamera

   private void startCamera(String caller) {
        System.out.println("ÇAĞIRAN " + caller);
        // bunların ikisi de çalışmadıkça bu metod çalışmasın.
        if (surfaceCreatedWorked && surfaceChangedWorked) {
            if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 1001);
                return;
            }
            Camera camera;
            try {
                camera = Camera.open();
            } catch (RuntimeException e) {
                Log.e("benimtagim", "init_camera: " + e);
                return;
            }
            Camera.Parameters param;
            param = camera.getParameters();
            //modify parameter
            param.setPreviewFrameRate(20);

            //test
            Camera.Size fittingSize = findFittingSize(param.getSupportedPreviewSizes());
            if (fittingSize != null) {
                param.setPreviewSize(fittingSize.width, fittingSize.height);
                android.view.ViewGroup.LayoutParams lp = mainactivity_surfaceview.getLayoutParams();
                System.out.println(surfaceWidth + "&&&" + surfaceHeight);
                // get the values that satisfy image ratio and surfacesize.
                //region
//                 because we are in portraid mode, surfacewidth should be multiply of cameraHeight and
//                 surfaceheight should be multiply of camerawidth @eddy
//                int newSurfaceWidth = 100;
//                int newSurfaceHeight = 100;
//                float widthFactor = (float) surfaceWidth / (float) fittingSize.height;
//                float heightFactor = (float) surfaceHeight / (float) fittingSize.width;
//                float selectedFactor = widthFactor > heightFactor ? widthFactor : heightFactor;
//                newSurfaceWidth = Math.round((float) fittingSize.height * selectedFactor);
//                newSurfaceHeight = Math.round((float) fittingSize.width * selectedFactor);
                //endregion
                //now its in a method. all cases has been handled.
                MySize mySize = getNewSurfaceSizes(surfaceWidth, surfaceHeight, fittingSize.width, fittingSize.height);
                lp.width = mySize.getWidth(); // required width
                lp.height = mySize.getHeight(); // required height
                mainactivity_surfaceview.setLayoutParams(lp);
            }

            camera.setParameters(param);
            camera.setDisplayOrientation(90);
            try {
                camera.setPreviewDisplay(mainactivity_surfaceview.getHolder());
                camera.startPreview();
                //camera.takePicture(shutter, raw, jpeg)
            } catch (Exception e) {
                Log.e("benimtagim", "init_camera: " + e);
                return;
            }


//
//        if (cam != null) {
//            Camera.Parameters param = cam.getParameters();
//            List<Camera.Size> sizes = param.getSupportedPreviewSizes();
//            for (Camera.Size size : sizes) {
//                System.out.println(size.width + " &&&&" + size.height);
//            }
//        } else {
//            Toast.makeText(MainActivity.this, "Kamera Yok", Toast.LENGTH_SHORT).show();
//        }
            surfaceCreatedWorked = false;
            surfaceChangedWorked = false;
        }
    }
...