Xamarin.Android Camera Touch для фокусировки - PullRequest
0 голосов
/ 28 января 2019

Я использую xamarin android, чтобы использовать встроенное приложение камеры, чтобы сделать фотографию, но есть две пропущенные вещи, которые я не могу сделать, и я гуглял их долгое время 1 - Я хочу получить сообщение или всплывающее окно (что угодно) послеНажав кнопку, чтобы сделать фотографию, например, «фотография сделана» 2 - я хочу, чтобы пользователь сфокусировался на любой точке камеры - НАЖМИТЕ НА ФОКУС *

async void TakePhotoButtonTapped(object sender, EventArgs e)
    {
        camera.StopPreview();

        Android.Hardware.Camera.Parameters parameters = camera.GetParameters();
        parameters.FocusMode = global::Android.Hardware.Camera.Parameters.FocusModeAuto;
        camera.SetParameters(parameters);

        var image = textureView.Bitmap;

        try
        {
            var absolutePath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDcim).AbsolutePath;
            var folderPath = absolutePath + "/Camera";
            var filePath = System.IO.Path.Combine(folderPath, string.Format("photo_{0}.jpg", Guid.NewGuid()));

            var fileStream = new FileStream(filePath, FileMode.Create);
            await image.CompressAsync(Bitmap.CompressFormat.Jpeg, 92, fileStream);
            fileStream.Close();
            image.Recycle();

            var intent = new Android.Content.Intent(Android.Content.Intent.ActionMediaScannerScanFile);
            var file = new Java.IO.File(filePath);
            var uri = Android.Net.Uri.FromFile(file);
            intent.SetData(uri);
            MainActivity.Instance.SendBroadcast(intent);

        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(@"               ", ex.Message);
        }

        camera.StartPreview();



    } 

Я пробовал это, но не работает

public void OnAutoFocus(bool success, Android.Hardware.Camera camera)
    {
        var parameters = camera.GetParameters();
        if (parameters.FocusMode != Android.Hardware.Camera.Parameters.FocusModeContinuousPicture)
        {
            parameters.FocusMode = Android.Hardware.Camera.Parameters.FocusModeContinuousPicture;

            if (parameters.MaxNumFocusAreas > 0)
            {
                parameters.FocusAreas = null;
            }
            camera.SetParameters(parameters);
            camera.StartPreview();
        }
    }

    public bool OnTouch(Android.Views.View view, MotionEvent e)
    {
        if (camera != null)
        {
            var parameters = camera.GetParameters();
            camera.CancelAutoFocus();
            Rect focusRect = CalculateTapArea(e.GetX(), e.GetY(), 1f);

            if (parameters.FocusMode != Android.Hardware.Camera.Parameters.FocusModeAuto)
            {
                parameters.FocusMode = Android.Hardware.Camera.Parameters.FocusModeAuto;
            }
            if (parameters.MaxNumFocusAreas > 0)
            {
                List<Area> mylist = new List<Area>();
                mylist.Add(new Android.Hardware.Camera.Area(focusRect, 1000));
                parameters.FocusAreas = mylist;
            }

            try
            {
                camera.CancelAutoFocus();
                camera.SetParameters(parameters);
                camera.StartPreview();
                camera.AutoFocus(this);
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.Write(ex.StackTrace);
            }
            return true;
        }
        return false; 
    }

    private Rect CalculateTapArea(object x, object y, float coefficient)
    {
        var focusAreaSize = 500;
        int areaSize = Java.Lang.Float.ValueOf(focusAreaSize * coefficient).IntValue();

        int left = clamp((int)x - areaSize / 2, 0, textureView.Width - areaSize);
        int top = clamp((int)y - areaSize / 2, 0, textureView.Height - areaSize);

        RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
        Matrix.MapRect(rectF);

        return new Rect((int)System.Math.Round(rectF.Left), (int)System.Math.Round(rectF.Top), (int)System.Math.Round(rectF.Right), (int)System.Math.Round(rectF.Bottom));
    }

    private int clamp(int x, int min, int max)
    {
        if (x > max)
        {
            return max;
        }
        if (x < min)
        {
            return min;
        }
        return x;
    }
}


----------

1 Ответ

0 голосов
/ 28 января 2019

Для фокусировки камеры при прикосновении к предварительному просмотру вам потребуется:

  1. Добавить обработчик сенсорного события для прослушивания пользователя, касающегося предварительного просмотра
  2. Получить координаты X и Yиз этого события касания, которые обычно находятся в аргументах события
  3. Создайте прямоугольник для фокусировки, чтобы сообщить Android-камере, где фокусироваться и в какой области
  4. Установите FocusAreas и MeteringAreas наCamera.Parameters от вашего прямоугольника
  5. Установите новый Camera.Parameters на камере
  6. Установите AutoFocus обратный вызов на камеру
  7. Когда сработает обратный вызов, удалите обратный вызовс камеры и отмените автофокусировку

Чтобы уведомить пользователя о снимке, вы можете использовать Toast или создать область предварительного просмотра, в которой вы хотите показывать такие сообщения.От вас зависит, как вы хотите уведомить пользователя.

...