2

ライブラリから写真を選択するか、カメラで写真を撮り、結果をビューに表示したい(ImageView)

しかし、これを含むいくつかの投稿によると、私が使用するMvxHttpImageViewには、画像を表示するためのURIが必要です(ファイルシステムまたはカメラのどちらからのものか)。これは、ストリームをファイルに変換し、URIを取り戻すことを意味します。

私はその仕事をするPictureServiceを書きました:

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.を使用して、受信したものをViewModelのプロパティにMemoryStream収集します。pictureStreambyte[]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.それだけです-エラー処理を追加してテストを行うこともできますが


このアプローチは、byte[]からのMvvmCrossAndroidBindImageへの回答から採用されています。

その質問で述べたように、別のアプローチは、ImageView代わりにカスタムバインディングを備えた標準を使用することです。


標準のビュー/ウィジェットに基づいてカスタムビュー/ウィジェットを作成する方法の詳細(<yourapp.namespace.to.MyImageView ... />省略形に置き換える方法を含む)については、 http://slodge.blogspot.co.uk/2012/10/creating-custom-views-is-easy<MyApp.MyImageView ... />を参照してください。 -to-do.html

于 2013-01-17T00:26:18.073 に答える