2016-12-07 6 views
3

私のアプリでカメラのページのためにユーザーが手動でフォーカスするとき(フォーカスをタップ)に基本サークルを表示したいとします。カメラがフォーカスされているときにビジュアルインジケータを実装する方法

私は既にタップでオートフォーカスを実装していますが、焦点が合っている円を描く方法と、ビューに焦点が合わなくなったときにそれを解除する方法がわかりません。インジケータは、最終的な写真の一部であってはならず、カメラの焦点が合っているかどうかにかかわらず、ユーザーのガイドと同じです。

は、ここで私がこれまで持っているものです。

public class AutoFocusCallback : Java.Lang.Object, IAutoFocusCallback 
{ 
    public void OnAutoFocus(bool success, Android.Hardware.Camera camera) 
    { 
     var parameters = camera.GetParameters(); 
     var supportedFocusModes = parameters.SupportedFocusModes; 

     if (string.IsNullOrEmpty(parameters.FocusMode)) 
     { 
      string focusModeContinuous = Android.Hardware.Camera.Parameters.FocusModeContinuousPicture; 
      string focusModeAuto = Android.Hardware.Camera.Parameters.FocusModeAuto; 

      if (supportedFocusModes != null && supportedFocusModes.Any()) 
      { 
       if (supportedFocusModes.Contains(focusModeContinuous)) 
       { 
        parameters.FocusMode = focusModeContinuous; 
       } 
       else if (supportedFocusModes.Contains(focusModeAuto)) 
       { 
        parameters.FocusMode = focusModeAuto; 
       } 
      } 
     } 

     if (supportedFocusModes != null && supportedFocusModes.Any()) 
     { 
      if (parameters.MaxNumFocusAreas > 0) 
      { 
       parameters.FocusAreas = null; 
      } 

      if (success) 
      { 
       CameraPage cameraPage = new CameraPage(); 
       Canvas canvas = new Canvas(); 
       cameraPage.Draw(canvas); 
      } 
      camera.SetParameters(parameters); 
      camera.StartPreview(); 
     } 
    } 
} 

public bool OnTouch(Android.Views.View v, 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(new AutoFocusCallback()); 
     } 
     catch (System.Exception ex) 
     { 
      Console.WriteLine(ex.ToString()); 
      Console.Write(ex.StackTrace); 
     } 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

private Rect CalculateTapArea(object x, object y, float coefficient) 
{ 
    var focusAreaSize = Math.Max(textureView.Width, textureView.Height)/8; //Recommended focus area size from the manufacture is 1/8 of the image 
    int areaSize = focusAreaSize * (int)coefficient; 

    int left = clamp(Convert.ToInt32(x) - areaSize/2, 0, textureView.Width - areaSize); 
    int top = clamp(Convert.ToInt32(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; 
} 

public override void Draw(Canvas canvas) 
{ 
    base.Draw(canvas); 
    Paint p = new Paint(); 
    p.Color = Android.Graphics.Color.White; 
    p.SetStyle(Paint.Style.Stroke); 
    p.StrokeWidth = 3; 
    canvas.DrawCircle(300, 300, 100, p); 
} 

例えばこの絵のように:

enter image description here

これは私のXamarin.Forms Androidアプリです。

編集:ここではカメラのAndroidのソースコードのコピーですが、わからないどこに指標を作っている:なし公式の答えと

https://android.googlesource.com/platform/packages/apps/Camera.git/+/refs/heads/marshmallow-release/src/com/android/camera

同様のSOの記事:

How to implement tap to focus indicator in android camera?

Implement indicator on tap to focus in camera [android]

Android Camera2 - Draw circle focus area

ご覧のとおり、複数の人に同じ質問がありますが、回答はありません。まだ不明な点がある場合は教えてください。

+0

誰かが私になぜわからないのか教えてもらえますか?私はこれをさらに編集していますが、私はかなり明確だと思います。私は描画したい視覚インジケーターの写真を追加しました。 – Euridice01

+1

私はこれが受け入れられる質問だと思う、SOの人々は、しかし、おどることができます。 – jdmdevdotnet

+0

私にもよく見え、完全に有効です。 – Basic

答えて

1

私は既にオートフォーカスをタップで実装していますが、焦点が合っている円を描く方法と、ビューに焦点が合わなくなったときに、カメラがフォーカスされたときに再描画を続ける方法がわかりません。

システムカメラを起動するIntentを使用して、私はシステムのカメラビューにフォーカス円を追加することが可能であるかわからない場合は、私にはシステムカメラのようなルックスを掲載絵。しかし、私はおそらくあなた自身でカメラをホストするのにSurfaceViewまたはTextureViewを使用したと思います。

もしそうなら、もっとも簡単な方法はImageViewをレイアウトに置き、可視性を変更し、カメラのフォーカス状態に応じてをリセットすることです。画像ソースは透明なものである必要があります。たとえば、私はthis oneを使用しました。その後、私のレイアウトはとても似ている:私はそれがTextureViewを使用して、私のシナリオを満たすようにするためにあなたのコードを少し変更した

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
    <TextureView android:id="@+id/textureView" 
       android:layout_height="match_parent" 
       android:layout_width="match_parent" /> 

    <Button android:id="@+id/take_photo" 
     android:layout_height="wrap_content" 
     android:layout_width="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_centerHorizontal="true" 
     android:text="@string/takephoto" /> 

    <ImageView android:id="@+id/focuscircle" 
      android:layout_height="80dp" 
      android:layout_width="80dp" 
      android:layout_centerInParent="true" 
      android:src="@drawable/FocusCircle" 
      android:visibility="invisible" /> 
</RelativeLayout> 

private void _textureView_Touch(object sender, View.TouchEventArgs e) 
{ 
    if (_camera != null) 
    { 
     var parameters = _camera.GetParameters(); 
     _camera.CancelAutoFocus(); 
     Rect focusRect = CalculateTapArea(e.Event.GetX(), e.Event.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(new AutoFocusCallBack()); 

      MarginLayoutParams margin = new MarginLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WrapContent, 
      ViewGroup.LayoutParams.WrapContent)); 
      margin.SetMargins(focusRect.Left, focusRect.Top, 
       focusRect.Right, focusRect.Bottom); 
      RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(margin); 
      layoutParams.Height = 200; 
      layoutParams.Width = 200; 
      _focusimg.LayoutParameters = layoutParams; 
      _focusimg.Visibility = ViewStates.Visible; 
     } 
     catch (System.Exception ex) 
     { 
      Console.WriteLine(ex.ToString()); 
      Console.Write(ex.StackTrace); 
     } 
     //return true; 
    } 
    else 
    { 
     //return false; 
    } 
} 

そして、それはあなたがこのようAutoFocusCallBacksuccess状態でコーディングすることができ消えるように:

if (success) 
{ 
    Task.Delay(1000); 
    Activity1._focusimg.Visibility = ViewStates.Invisible; 
} 

ようにするために、ここで画面をタップすると、画像が見えるようにするコードがありますこれは、罰金、すべてのティムの作品

private Android.Hardware.Camera _camera; 
private TextureView _textureView; 

public static ImageView _focusimg; 

protected override void OnCreate(Bundle bundle) 
{ 
    base.OnCreate(bundle); 
    SetContentView(Resource.Layout.Main); 

    _textureView = (TextureView)this.FindViewById(Resource.Id.textureView); 
    _textureView.SurfaceTextureListener = this; 
    _textureView.Touch += _textureView_Touch; 

    var tpBtn = (Button)this.FindViewById(Resource.Id.take_photo); 
    tpBtn.Click += TpBtn_Click; 

    _focusimg = (ImageView)this.FindViewById(Resource.Id.focuscircle); 
} 

AutoFocusCallBackからアクセスImageViewは、あなたはそれxamarinで静的なものにすることができます私がTextureViewをタップしたときに、それがイベントを起こさないことがわかったとき、私はこの問題を深く掘り下げませんでした。

コード内で行ったようにCanvasに円を動的に描く方法もありましたが、この方法ではデモ応答が遅くなりましたが、この問題を深く掘り下げませんでした。とにかく、私はデモが必要な場合は、コメントを残して、画像を使用して最初の方法は簡単だと思う。

+0

偉大な心は似ていると思います!私はこの問題を解決するためにあなたと昨日同じことをしました。私は私の解決策を共有することができます(あなたのものほど正確ではないかもしれませんが)。私はそれについてのフィードバックが大好きです。私は少し後でそれを共有します:) – Euridice01

+0

グレース、この部分は:「時々私がTextureViewをタップしたときに、_textureView_Touchイベントを発生させず、この問題を深く掘り下げませんでした。これがなぜ起こったのかあなたは何か考えがありますか? – Euridice01

+0

@ Euridice01、わからない、もし 'Image'を' ViewStates.Invisible'にセットしても、それはまだ空間を取るでしょう、私は画像をタップしたかもしれません...おそらく、それを 'ViewStates.Gone '。 –

関連する問題