2016-12-09 66 views
2

我有一个在Azure中设置的数据库,以及其他一些数据类型,它会放置一些图片。保存照片的列是图像数据类型。我插入看起来像这样(的PIC转换为二进制文件)Azure数据库和照片

public void Insert()  
    { 
    string filepath = "C:\\PictureFolder\\MyPhoto.jpg"; 
    byte[] Pic = File.ReadAllBytes(filepath); 

    DataContex oDc = new DataContex(); 

    tblShip otblShip = new tblShip; 

    otblShip.Id = Guid.NewGuid(); 
    otblShip.Name = "Enterprise"; 
    otblShip.Picture = Pic; 

    oDc.tblShips.InsertOnSubmit(oMyTable); 

    oDc.SubmitChanges(); 

    } 

插入的作品,当我检查我的表在Azure中,一个二进制值插入图片列。我如何恢复它,以及如何在WPF界面中显示实际的照片?

+0

您应该探索将图像存储在Blob存储中并将其ID或路径存储在数据库中的可能性。存储成本更便宜。 – CSharpRocks

回答

0

我同意@CSharpRocks,因为您已经在使用Azure,因此您可以非常方便地进行一些研究并将图片存储在BlobStorage存储帐户中。与传统数据库存储相比,存储帐户具有许多优点。

你可以找到更多关于存储帐户和如何开始使用它here

但这个问题是关于如何检索图像并将其显示在您的WPF应用程序中,根据您自己的问题。因此,让我们来看看:

你已经拥有你的图像存储在数据库中,这样你就可以获取相关tblShip实体,使用主键值(或任何其他查询):

假设你有这样的某处您的XAML视图:

<Image Name="imgControl" ... /> 

你可以展示你的形象是这样的:

private void DisplayImageFromDb(Guid id) 
{ 
    using (var context = new DataContext()) 
    { 
     var item = context 
      .tblShips 
      .AsNoTracking() 
      .FirstOrDefault(x => x.Id == id); 

     if (item == null) 
      throw new Exception("Image could not be found!"); 

     //Convert the byte[] to a BitmapImage 
     BitmapImage img = new BitmapImage(); 
     MemoryStream ms = new MemoryStream(item.Picture); 
     img.BeginInit(); 
     img.StreamSource = ms; 
     img.EndInit(); 

     //assign the image to the Source property of the Image Control. 
     imgControl.Source = img; 
    } 
} 

这会工作正常,但如果您使用更多的WPF(MVVM)导向的方式会更好。假设你有xaml视图,但是你正在使用MVVM。因而,图像控件绑定到一个视图模型属性:

<Image Grid.Row="1" 
     Source="{Binding ImageSource, Converter={StaticResource ByteArrayToImageConverter}}"/> 

在你看来的资源,你声明的转换器:

<Windows.Resources> 
    <local:ByteArrayToImageConverter x:Key="ByteArrayToImageConverter" /> 
</Window.Resources> 

这里是转换器的实现:

using System; 
using System.Globalization; 
using System.IO; 
using System.Windows.Data; 
using System.Windows.Media.Imaging; 

namespace WpfApp1 
{ 
    public class ByteArrayToImageConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      if (value == null) return null; 

      //Convert the byte[] to a BitmapImage 
      BitmapImage img = new BitmapImage(); 
      MemoryStream ms = new MemoryStream((byte[])value); 
      img.BeginInit(); 
      img.StreamSource = ms; 
      img.EndInit(); 

      return img; 
     } 

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

现在你有一个干净的分离关注,所以你的用户界面是谁实际上是howing的形象和你的视图模型应该只从数据库中加载它并操纵域实体:

您的视图模型必须申报用于绑定的ImageSource属性:

private byte[] imageSource; 
public byte[] ImageSource 
{ 
    get { return imageSource; } 
    set 
    { 
     imageSource = value; 
     //must implement property changed notifications 
     OnPropertyChanged(new PropertyChangedEventArgs("ImageSource")); 
    } 
} 

这一切重构后,在视图模型方法,加载图像可以这样实现:

private void DisplayImageFromDb(int id) 
{ 
    using (var context = new DataContext()) 
    { 
     var item = context 
      .tblShips 
      .AsNoTracking() 
      .FirstOrDefault(x => x.Id == id); 

     if (item == null) 
      throw new Exception("Image could not be found!"); 

     //Assign the property and let the binding do the work 
     ImageSource = item.Picture; 
    } 
} 

你一定会得到相同的结果,但你现在有一个很好的分离应用程序,将允许更容易维护,因为它的发展。

希望这会有所帮助!

+0

.AsNoTracking()给出一个红色的波浪曲线,要求提供程序集引用或指令。我添加了System.Data.Entity;将System.Data.Linq;仍然没有去。 – Coolhand

+0

@Coolhand你可以安全地删除这条线的情况。我使用EF DbContext测试了它,而您似乎正在使用另一种数据上下文。 –

+0

我的DataContext来自我的dbml。我不知道EF DbContext是什么。 – Coolhand

0

这里的一切都是硬编码的,但这里是我如何将一个100 x 100像素的图像 往返于Db。我明白有更好的方式来存储图像,但对我的目的来说,这很好!

 public void InsertPhotoToDb() 
    { 
     string filepath = "C:\\TFS\\Enterprise.jpg"; 
     byte[] Pic = File.ReadAllBytes(filepath); 

     ArmadaDataContext oDc = new ArmadaDataContext(); 

     tblPictureTest otblPictureTest = new tblPictureTest(); 
     otblPictureTest.Id = Guid.NewGuid(); 

     otblPictureTest.FileName = "Enterprise"; 
     otblPictureTest.Photo = Pic; 
     oDc.tblPictureTests.InsertOnSubmit(otblPictureTest); 
     oDc.SubmitChanges(); 

     oDc = null; 
    } 

    private void DisplayImageFromDb() 
    { 
     using (var oDc = new ArmadaDataContext()) 
     { 
      var item = oDc 
       .tblPictureTests 
       .FirstOrDefault(x => x.FileName == "Enterprise"); // Retrieves using the filename 


      // If retrieving using the GUID, use the line below instead. 
      // .FirstOrDefault(x => x.Id == Guid.Parse("58b44a51-0627-43fe-9563-983aebdcda3a")); 


      if (item == null) 
       throw new Exception("Image could not be found!"); 

      //Convert the byte[] to a BitmapImage 
      BitmapImage img = new BitmapImage(); 
      MemoryStream ms = new MemoryStream(item.Photo.ToArray()); 
      img.BeginInit(); 
      img.StreamSource = ms; 
      img.EndInit(); 

      //assign the image to the Source property of the Image box in the UI. 
      imgPhoto.Source = img; 
     } 
    }