Есть ли способ использовать функции камеры в формах Xamarin без загрузки каких-либо дополнительных пакетов NuGet? - PullRequest
0 голосов
/ 16 марта 2020

В настоящее время я создаю проект, который позволяет пользователю сфотографировать что-то и использовать эту фотографию. Мне было интересно, есть ли какие-либо другие методы, которые не требуют от меня загрузки каких-либо плагинов или пакетов NuGet?

1 Ответ

0 голосов
/ 18 марта 2020

Вам необходимо создать ICameraPickerService в формах Xamarin:

public interface IPhotoPickerService
{
    Task<byte[]> GetImageStreamAsync();
}

В iOS, создать CameraPickerService :

[assembly: Dependency(typeof(CameraPickerService))]
namespace DependencyServiceDemos.iOS
{
    public class CameraPickerService: ICameraPickerService
    {
        TaskCompletionSource<byte[]> taskCompletionSource;
        UIImagePickerController imagePicker;

        public Task<byte[]> GetImageStreamAsync()
        {
            // Create and define UIImagePickerController
            imagePicker = new UIImagePickerController
            {
                SourceType = UIImagePickerControllerSourceType.Camera,
                MediaTypes = UIImagePickerController.AvailableMediaTypes(UIImagePickerControllerSourceType.Camera)
            };

            // Set event handlers
            imagePicker.FinishedPickingMedia += OnImagePickerFinishedPickingMedia;
            imagePicker.Canceled += OnImagePickerCancelled;

            // Present UIImagePickerController;
            UIWindow window = UIApplication.SharedApplication.KeyWindow;
            var viewController = window.RootViewController;
            viewController.PresentModalViewController(imagePicker, true);

            // Return Task object
            taskCompletionSource = new TaskCompletionSource<byte[]>();
            return taskCompletionSource.Task;
        }

        void OnImagePickerFinishedPickingMedia(object sender, UIImagePickerMediaPickedEventArgs args)
        {
            UIImage image = args.EditedImage ?? args.OriginalImage;

            if (image != null)
            {
                // Convert UIImage to .NET Stream object
                NSData data;
                if (args.ReferenceUrl.PathExtension.Equals("PNG") || args.ReferenceUrl.PathExtension.Equals("png"))
                {
                    data = image.AsPNG();
                }
                else
                {
                    data = image.AsJPEG(1);
                }
                Stream stream = data.AsStream();

                UnregisterEventHandlers();

                // Set the Stream as the completion of the Task
                taskCompletionSource.SetResult(data.ToArray());
            }
            else
            {
                UnregisterEventHandlers();
                taskCompletionSource.SetResult(null);
            }
            imagePicker.DismissModalViewController(true);
        }

        void OnImagePickerCancelled(object sender, EventArgs args)
        {
            UnregisterEventHandlers();
            taskCompletionSource.SetResult(null);
            imagePicker.DismissModalViewController(true);
        }

        void UnregisterEventHandlers()
        {
            imagePicker.FinishedPickingMedia -= OnImagePickerFinishedPickingMedia;
            imagePicker.Canceled -= OnImagePickerCancelled;
        }
    }
}

Не забудьте добавить разрешение в Info.plist:

<key>NSCameraUsageDescription</key>
<string>Use Camera</string>

Кроме того , iOS необходимо запустить на физическом устройстве.

В Android создайте CameraPickerService :

[assembly: Dependency(typeof(CameraPickerService))]
namespace DependencyServiceDemos.Droid
{
    public class CameraPickerService : ICameraPickerService
    {
        public Task<byte[]> GetImageStreamAsync()
        {
            // Define the Intent for getting images
            Intent getImageByCamera = new Intent("android.media.action.IMAGE_CAPTURE");


            // Start the camera (resumes in MainActivity.cs)
            MainActivity.Instance.StartActivityForResult(
                getImageByCamera,
                MainActivity.PickImageId);

            // Save the TaskCompletionSource object as a MainActivity property
            MainActivity.Instance.PickImageTaskCompletionSource = new TaskCompletionSource<byte[]>();

            // Return Task object
            return MainActivity.Instance.PickImageTaskCompletionSource.Task;
        }
    }
}

Добавление разрешения в AndroidMainfest. xml:

<uses-permission android:name= "android.permission.CAMERA" />
<uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" />

Получить данные изображения в MainActivity :

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    internal static MainActivity Instance { get; private set; }

    public int CAMERA_JAVA_REQUEST_CODE = 1;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(savedInstanceState);
        Instance = this;
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        LoadApplication(new App());
        DependencyService.Register<ITextToSpeechService, TextToSpeechService>();
    }

    // Field, property, and method for Picture Picker
    public static readonly int PickImageId = 1000;

    public TaskCompletionSource<byte[]> PickImageTaskCompletionSource { set; get; }

    protected override void OnActivityResult(int requestCode, Result resultCode, Intent intent)
    {
        base.OnActivityResult(requestCode, resultCode, intent);

        if (requestCode == PickImageId)
        {
            if ((resultCode == Result.Ok) && (intent != null))
            {
                Bundle bundle = intent.Extras;
                Bitmap bitmap = (Bitmap)bundle.Get("data");
                //// Set the Stream as the completion of the Task
                MemoryStream memoryStream = new MemoryStream();
                bitmap.Compress(Bitmap.CompressFormat.Jpeg, 50, memoryStream);
                PickImageTaskCompletionSource.SetResult(memoryStream.ToArray());

            }
            else
            {
                PickImageTaskCompletionSource.SetResult(null);
            }
        }
    }
}

Наконец, показать изображение в ContentPage форм:

    async void OnPickPhotoButtonClicked(object sender, EventArgs e)
    {
        (sender as Button).IsEnabled = false;

        byte[] data = await DependencyService.Get<IPhotoPickerService>().GetImageStreamAsync();
        MemoryStream stream = new MemoryStream(data);
        if (stream != null)
        {
            image.Source = ImageSource.FromStream(() => stream) ;
        }

        (sender as Button).IsEnabled = true;
    }

Эффект:

enter image description here

Примечание: Если вы хотите выбрать фотографию из библиотеки изображений, вы можете посмотреть на этот официальный документ .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...