我想从图库中选择图片或使用相机拍摄图片并将结果显示到视图(ImageView)

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

我写了一个Picture Service来完成这项工作:

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;
    }

}


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


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


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

要么

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

谢谢你的帮助。

最佳答案

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

1.使用MemoryStream将接收到的pictureStream收集到ViewModel的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[]上公开MyImageView属性-当设置了byte[]时,请使用BitmapFactory.DecodeByteArray和从传入的字节渲染图片

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.在axml中使用SetBitmap代替普通的<yourapp.namespace.to.MyImageView ... />

4.在axml中,将View <ImageView ... />属性绑定到源ViewModel byte[]属性。

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


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



此方法是根据MvvmCross Android Bind Image from byte[]的答案改编而成的

如该问题所述,另一种方法是使用带有自定义绑定的标准byte[]



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

10-04 22:28
查看更多