Azure数据库和照片

时间:2016-12-09 18:36:23

标签: c# image azure

我在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中检查我的表时,在Picture列中插入二进制值。如何取回,以及如何在WPF界面中显示实际照片?

2 个答案:

答案 0 :(得分: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控件绑定到viewmodel属性:

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

现在您可以清楚地分离关注点,以便您的UI实际显示图像,并且您的viewmodel应该只从数据库加载它并操纵域实体:

您的viewmodel必须声明用于绑定的ImageSource属性:

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

在完成所有这些重构之后,viewmodel中加载图像的方法可以像这样实现:

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

你肯定会得到相同的结果,但你现在有一个非常好的分离应用程序,可以随着它的发展更容易维护。

希望这有帮助!

答案 1 :(得分: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;
        }
    }