2016-12-09 90 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; 
     } 
    }