読者です 読者をやめる 読者になる 読者になる

がりらぼ

WindowsRuntimeの応援ブログ

byteデータをImageコントロールにBindingする

WindowsRuntime

Imageコントロールに画像データをバインドするとき、モデルはどういうデータを保持すべきかなーって思った時、 通常ならばSourceプロパティにバインドを行うのでBitmapImageクラスをモデルに持つべきかなと思ったけどBitmapImageクラスをモデルでもっちゃうとあとでbyteデータにおとして保存とかなると方法がみつからなかったので モデルでbyte[]として画像データをもつことにして、それをBindingするのがいいかなーと思いました。

というわけでモデルクラスはこんな感じのImageModelクラス

public class ImageModel:INotifyPropertyChanged
{
    public ImageModel()
    {
        ImageData=new byte[]{};
    }

    private byte[] imageData;

    public byte[] ImageData
    {
        get { return imageData; }
        set { imageData = value; OnPropertyChanged("ImageData");}
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string name)
    {
        if(PropertyChanged!=null)
        PropertyChanged(this,new PropertyChangedEventArgs(name));
    }
}

Converterを使ってByteデータからBitmapImageに変換する

 public class ByteToBitmapImageConverter : IValueConverter
 {
     public object Convert(object value, Type targetType, object parameter, string language)
     {
         if (value != null)
         {

             var bytes = (byte[]) value;
             var myBitmapImage = new BitmapImage();
             var stream = new InMemoryRandomAccessStream();
             var writer = new DataWriter(stream.GetOutputStreamAt(0));

             writer.WriteBytes(bytes);
             writer.StoreAsync().GetResults();
             myBitmapImage.SetSource(stream);

             return myBitmapImage;
         }
         else
         {
             return new BitmapImage();
         }

     }

     public object ConvertBack(object value, Type targetType, object parameter, string language)
     {
         throw new NotImplementedException();
     }
 }

ImageコントロールではConverterをつけてbindingする。 ConverterをResourceにいれておくこと

<Image Source="{Binding ImageData,Converter={StaticResource ByteToBitmapImageConverter}}" />

DataContextにいれて

this.DataContext = new ImageModel();

ロードしたときに適当な画像を選んでもらってモデルにいれる

private async void Grid_Loaded(object sender, RoutedEventArgs e)
{
    FileOpenPicker openPicker = new FileOpenPicker();
    openPicker.ViewMode = PickerViewMode.Thumbnail;
    openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
    openPicker.FileTypeFilter.Add(".jpg");
    openPicker.FileTypeFilter.Add(".jpeg");
    openPicker.FileTypeFilter.Add(".png");

    StorageFile file = await openPicker.PickSingleFileAsync();
    if (file != null)
    {

        var stream = await file.OpenAsync(FileAccessMode.Read);
        var size = stream.Size;
        byte[] bytes = new byte[size];
        var reader = new DataReader(stream.GetInputStreamAt(0));
        await reader.LoadAsync((uint) size);
        reader.ReadBytes(bytes);
        (DataContext as ImageModel).ImageData = bytes;
    }
}

画像がアップロード出来ないので結果がのせれなくて悲しい... BitmapImageにバインドはできたけどBitmapImageからbyteに逆コンバートが今のところ思いつかないのが謎