我在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界面中显示实际照片?
答案 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;
}
}