Issues taking images and showing them with MvvmCro

2019-03-05 09:10发布

I want to take a photo with the camera and show it on the page I am at

So I have a ViewModel where I both take the picture and show it

public class CamViewModel : MvxViewModel,
    IMvxServiceConsumer<IInstalledMeter>,
    IMvxServiceConsumer<ICamaraService>        
{
    public CamViewModel()
    {
        this.GetService<ICamaraService>().PhotoSavedEvent += PhotoSaved;

        if (!String.IsNullOrEmpty(this.GetService<IInstalledMeter>().ImagePath))
        {
            ImagePath = this.GetService<IInstalledMeter>().ImagePath;
        }

        TakePicture();
    }

    private string _imagePath;
    public string ImagePath
    {
        get { return _imagePath; }
        set { _imagePath = value; FirePropertyChanged("ImagePath"); }
    }

    //Navigate back to InstallUnit
    public IMvxCommand OpenCamaraCommand
    {
        get
        {
            return new MvxRelayCommand(TakePicture);
        }
    }

    private void PhotoSaved(object sender, PhotoSavedResultEventArgs e)
    {
        ImagePath = e.ImagePath;
    }

    private void TakePicture()
    {
        this.GetService<ICamaraService>().TakePhoto();
    }
}

This uses a CameraService that both takes the picture and saves the picture on isolated storage (I know, bad seperation of concern)

public class CamaraService : IMvxServiceConsumer<IMvxPictureChooserTask>, IMvxServiceConsumer<IMvxSimpleFileStoreService>, IMvxServiceConsumer<IInstalledMeter>, ICamaraService
{
    private const int MaxPixelDimension = 1024;
    private const int DefaultJpegQuality = 70;

    public event EventHandler<PhotoSavedResultEventArgs> PhotoSavedEvent;
    private void PhotoTaken(PhotoSavedResultEventArgs e)
    {
        if (PhotoSavedEvent != null)
        {
            PhotoSavedEvent(this, e);
        }
    }

    public string ImagePath { get; set; }

    public void TakePicture()
    {
        this.GetService<IMvxPictureChooserTask>().TakePicture(
            MaxPixelDimension, 
            DefaultJpegQuality,
            SavePicture, 
            () => { /* cancel is ignored */ });
    }
    public void TakePhoto()
    {
        TakePicture();
    }

    public void SavePicture(Stream image)
    {
        var newImage = Save(image);
        if (newImage != "")
        {
            DeleteOldImage(this.GetService<IInstalledMeter>().ImagePath);
            this.GetService<IInstalledMeter>().ImagePath = newImage;
            PhotoTaken(new PhotoSavedResultEventArgs {ImagePath = newImage});
        }
    }

    public void UpdateModel(string filename)
    {

    }

    public void DeleteOldImage(string fileName)
    {
        try
        {
            if (String.IsNullOrEmpty(fileName)) return;
            var fileService = this.GetService<IMvxSimpleFileStoreService>();
            fileService.DeleteFile(fileName);
        }
        catch
        {
        }
    }

    public string Save(Stream stream)
    {
        try
        {
            var fileName = Guid.NewGuid().ToString();
            var fileService = this.GetService<IMvxSimpleFileStoreService>();
            fileName = Path.Combine("Image", fileName);
            fileService.WriteFile(fileName, stream.CopyTo);
            return fileName;
        }
        catch (ThreadAbortException)
        {
            throw;
        }
        catch (Exception exception)
        {
            return "";
        }
    }
}

The View on Windows Phone to display the image is

<Views:BaseCamView
x:Class="UI.WP7.Views.InstallMeter.CamView"
xmlns:Views="clr-namespace:UI.WP7.Views.InstallMeter"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:nativeConverters="clr-namespace:UI.WP7.NativeConverters"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">

<Views:BaseCamView.Resources>
    <nativeConverters:PathToImageConverter x:Name="PathToImageConverter" />
</Views:BaseCamView.Resources>

<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <!--TitlePanel contains the name of the application and page title-->
    <StackPanel Grid.Row="0" Margin="12,17,0,28">
        <TextBlock Text="MY sdf" Style="{StaticResource PhoneTextNormalStyle}"/>
        <TextBlock Text="{Binding ImagePath}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>

    <Image Grid.Row="1" Source="{Binding ImagePath, Converter={StaticResource PathToImageConverter}}"  Height="200" Width="700" Stretch="Uniform" />

</Grid>

And this view uses a converter to convert the path to a bitmapimage

public class PathToImageConverter : IValueConverter, IMvxServiceConsumer<IMvxSimpleFileStoreService>
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        byte[] contents = null;
        try
        {
            var file = this.GetService();
            file.TryReadBinaryFile((string)value, out contents);
        }
        catch (Exception)
        {
            // masked
        }

        if (contents == null)
            return null;

        using (var stream = new MemoryStream(contents))
        {
            var image = new BitmapImage();
            image.SetSource(stream);
            return image;
        }
    }

But when ever I try to take a picture this bit in the converter returns null

if (contents == null)
        return null;

So I presume that means the image is not accessable / saved or the filename is wrong, but not sure where the error happens

标签: c# mvvmcross
1条回答
仙女界的扛把子
2楼-- · 2019-03-05 09:48

I think you need to step through and debug the photo code.

You could also try adding some trace to the Exception catch handlers.

One guess is that your GUID based file name includes invalid characters - see http://msdn.microsoft.com/en-us/library/system.io.path.getinvalidpathchars%28v=vs.95%29.aspx Try Guid.ToString("N") + ".jpg" for a slightly less mangled file name

But really you need to trace through the code and find out where the error is occurring.

查看更多
登录 后发表回答