2

我想从库中选择一张图片或用相机拍照并将结果显示给视图(ImageView)

但是根据包括这篇文章在内的一些帖子,我使用的 MvxHttpImageView 需要一个 Uri 来显示图像(无论它来自文件系统还是相机)。这意味着,将 Stream 转换为文件并取回 Uri。

我写了一个图片服务来完成这项工作:

public class PictureService : IPictureService, 
    IMvxServiceConsumer<IMvxPictureChooserTask>, 
    IMvxServiceConsumer<IMvxSimpleFileStoreService>
{
    private const int MaxPixelDimension = 1024;
    private const int DefaultJpegQuality = 92;

    public void TakeNewPhoto(Action<string> onSuccess, Action<string> onError)
    {
        this.GetService<IMvxPictureChooserTask>().TakePicture(
            PictureService.MaxPixelDimension,
            PictureService.DefaultJpegQuality,
            pictureStream =>
            {
                var newPictureUri = this.Save(pictureStream);
                if (!string.IsNullOrWhiteSpace(newPictureUri))
                    onSuccess(newPictureUri);
                else
                    onError("No picture selected");
            },
            () => { /* cancel is ignored */ });
    }

    public void SelectExistingPicture(Action<string> onSuccess, Action<string> onError)
    {
        this.GetService<IMvxPictureChooserTask>().ChoosePictureFromLibrary(
            PictureService.MaxPixelDimension,
            PictureService.DefaultJpegQuality,
            pictureStream =>
            {
                var newPictureUri = this.Save(pictureStream);
                if (!string.IsNullOrWhiteSpace(newPictureUri))
                    onSuccess(newPictureUri);
                else
                    onError("No photo taken");
            },
            () => { /* cancel is ignored */ });
    }

    private string Save(Stream stream)
    {
        string fileName = null;
        try
        {
            fileName = Guid.NewGuid().ToString("N");
            var fileService = this.GetService<IMvxSimpleFileStoreService>();
            fileService.WriteFile(fileName, stream.CopyTo);
        }
        catch (Exception)
        {
            fileName = null;
        }

        return fileName;
    }

}

但出于隐私原因,我不想将图片保存在文件系统上。工作流程是:

  1. 拍摄或选择照片
  2. 在屏幕上显示(带有附加信息)
  3. 将我的模型保存在将图像发送到云的服务器上:不在设备上跟踪

我的问题是:如何在不保存文件系统的情况下处理包含图片数据的流?

或者

如何使用用户无法访问的临时存储系统(忽略“根”设备案例)?

谢谢你的帮助。

4

1 回答 1

3

您可以尝试创建自己的自定义控件ImageView

1.使用 aMemoryStream将接收到的数据收集到ViewModel 上的pictureStream一个属性中,例如byte[]MyBytes

pictureStream => {
     var memoryStream = new MemoryStream();
     pictureStream.CopyTo(memoryStream);
     TheRawImageBytes = memoryStream.GetBuffer()
}

哪里TheRawImageBytes是:

private byte[] _theRawImageBytes;
public byte[] TheRawImageBytes
{
    get { return _theRawImageBytes; }
    set { _theRawImageBytes = value; RaisePropertyChanged(() => TheRawImageBytes); }
}

2.创建自己的MyImageView派生类ImageView,添加构造函数,然后在-上(context, attr)公开一个byte[]属性,然后使用并从传入字节呈现图片MyImageViewbyte[]BitmapFactory.DecodeByteArraySetBitmap

private byte[] _rawImage;
public byte[] RawImage
{
     get { return _rawImage; }
     set 
     {
             _rawImage = value;
             if (_rawImage == null)
                     return;

             var bitmap = BitmapFactory.DecodeByteArray(_rawImage, 0,_rawImage.Length);
             SetImageBitmap(bitmap);
     }
}

3.<yourapp.namespace.to.MyImageView ... />在axml中使用而不是普通的<ImageView ... />

4.在 axml 中将 Viewbyte[]属性绑定到源 ViewModelbyte[]属性。

local:MvxBind="{'RawImage':{'Path':'TheRawImageBytes'}}"

5.就是这样——尽管您可能想要添加一些错误处理并进行一些测试


这种方法改编自MvvmCross Android Bind Image from byte[]的答案

如该问题所述,另一种方法是使用ImageView具有自定义绑定的标准。


有关基于标准视图/小部件创建自定义视图/小部件的更多信息 - 包括如何<yourapp.namespace.to.MyImageView ... />用缩写替换<MyApp.MyImageView ... />,请参阅http://slodge.blogspot.co.uk/2012/10/creating-custom-views-is-easy -to-do.html

于 2013-01-17T00:26:18.073 回答