【问题标题】:Xamarin Forms - Xamarin Forms Labs Camera on Page Showing UpXamarin Forms - Xamarin Forms Labs 页面上的相机显示
【发布时间】:2014-09-13 19:57:51
【问题描述】:

有人在 Xamarin.Forms.Labs 的相机功能的 Xamarin.Forms 中有示例吗?

我试图让它工作,但它似乎根本不起作用。

这是我的代码:

public partial class CameraPictureInfoPage : ContentPage
{   
    public CameraPictureInfoPage ()
    {
        Image img = new Image ();
        this.Appearing += async (s, e) => {
            img.Source = await GetPicture (true);
        };


        this.Content = new StackLayout {
            Orientation = StackOrientation.Vertical,
            VerticalOptions = LayoutOptions.Center,
            WidthRequest = 250,
            Padding = 40, Spacing = 10,
            Children = {
                img
            }
        };
    }


    async Task<ImageSource> GetPicture(bool chooseNotTake){
        var mediaPicker = DependencyService.Get<IMediaPicker> (); 
        ImageSource imgSource  = null;
        if (mediaPicker != null) {
            Task<MediaFile> pick;
            if (chooseNotTake) {
                pick = mediaPicker.TakePhotoAsync (new CameraMediaStorageOptions {
                    DefaultCamera = CameraDevice.Rear, 
                    MaxPixelDimension = 1024,
                });
            } else {
                pick = mediaPicker.SelectPhotoAsync (new CameraMediaStorageOptions{ MaxPixelDimension = 1024 });
            } 

            await pick.ContinueWith (t => {
                if (!t.IsFaulted && !t.IsCanceled) {
                    var mediaFile = t.Result; 
                    MemoryStream mstr = new MemoryStream ();
                    mediaFile.Source.CopyTo (mstr);
                    imgSource = ImageSource.FromStream (() => mstr); 
                }
                return imgSource; 
            });
        }

        return imgSource;
    }
}

【问题讨论】:

    标签: xamarin.forms


    【解决方案1】:

    这对我有用:

    在 AppDelegate.cs 中的 iOS 项目中:

    public override bool FinishedLaunching (UIApplication app, NSDictionary options) { SetIoc();

        Forms.Init ();
    
        window = new UIWindow (UIScreen.MainScreen.Bounds); 
    
        window.RootViewController = App.GetMainPage ().CreateViewController ();
        window.MakeKeyAndVisible ();
    
        return true;
    }
    
    private void SetIoc ()
    {
        var resolverContainer = new SimpleContainer ();
        resolverContainer.Register<IDevice> (t => AppleDevice.CurrentDevice)
            .Register<IDisplay> (t => t.Resolve<IDevice> ().Display)
            .Register<IDependencyContainer> (t => resolverContainer);
    
        Resolver.SetResolver (resolverContainer.GetResolver ());
    }
    

    在表单项目中:

    private async Task<ImageSource> GetPicture(bool chooseNotTake){
      var mediaPicker = DependencyService.Get<IMediaPicker> (); 
      ImageSource imgSource  = null;
      if (mediaPicker != null) {
          Task<MediaFile> pick;
          if (!chooseNotTake) {
            pick = mediaPicker.TakePhotoAsync (new CameraMediaStorageOptions {
              DefaultCamera = CameraDevice.Rear, 
              MaxPixelDimension = 1024,
            });
          } else {
              pick = mediaPicker.SelectPhotoAsync (new CameraMediaStorageOptions{ MaxPixelDimension = 1024 });
          } 
    
         await pick.ContinueWith (t => {
            if (!t.IsFaulted && !t.IsCanceled) {
               var mediaFile = t.Result; 
               MemoryStream mstr = new MemoryStream();
               mediaFile.Source.CopyTo(mstr);
               imgSource = ImageSource.FromStream (() => mstr); 
        }
        return imgSource; 
      }
    }
    

    请记住,您可能需要通过其他方式存储图像流,否则它可能会过早被垃圾收集。


    要让拍照者在启动时出现,您必须避免 async 并连接到 Appearing 事件。在页面的构造函数中添加:

    public class PhotoPage :  ContentPage
    {
        Image img = new Image ();
        IMediaPicker picker = null; 
        Task<MediaFile> task = null;
    
        public PhotoPage ()
        {  
            img.WidthRequest = 60;
            img.HeightRequest = 60;
            img.BackgroundColor = Color.Silver;
    
            this.Content = new StackLayout {
                Orientation = StackOrientation.Vertical,
                VerticalOptions = LayoutOptions.Center,
                BackgroundColor = Color.Aqua,
                WidthRequest = 250,
                Padding = 40, Spacing = 10,
                Children = {
                    img, 
                }
            }; 
    
    
            this.Appearing += (s, e) => { 
                picker = DependencyService.Get<IMediaPicker> ();  
                task = picker.SelectPhotoAsync (new CameraMediaStorageOptions{ MaxPixelDimension = 1024 });  
            }; 
    
            Device.StartTimer (TimeSpan.FromMilliseconds (250), () => {
                if (task != null) {
                    if (task.Status == TaskStatus.RanToCompletion) {
                        Device.BeginInvokeOnMainThread (() => {
                            img.Source = ImageSource.FromStream (() => task.Result.Source);
                        });  
                    }
    
                    return  task.Status != TaskStatus.Canceled
                        && task.Status != TaskStatus.Faulted
                        && task.Status != TaskStatus.RanToCompletion;
                }
                return true;
            }); 
        }
    }
    

    【讨论】:

    • 它仍然不起作用,iamge 没有出现,我得到唯一一次可以激活的操作。我的代码可以在你的电脑上运行吗?
    • 修改后的代码在我的电脑上运行,不调用GetPicture()的版本
    • 添加了完整示例。用计时器监控任务解决线程问题
    • 我得到了同样的错误:一次只能激活一个操作你在类的顶部“使用”什么库,你知道为什么会发生这个错误吗?
    • this.Appearing += (s, e) => { picker = DependencyService.Get (); task = picker.SelectPhotoAsync (new CameraMediaStorageOptions{ MaxPixelDimension = 1024 }); };这些是出现错误的行,我认为是因为在我拍照后它会将我带回屏幕并尝试再次执行 Appearing 事件,有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多