我正在Silverlight中创建应用程序。现在只有一个DataGrid。我正在使用WCF RIA服务从数据库中获取数据。一切正常,期待图像。我将图像作为字节数组并尝试使用Converter将它们转换为BitmapImage。我想在DataGrid的RowDetailsTemplate中显示图像。
这是:
<sdk:DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel>
<StackPanel>
<Image x:Name="thumbNail" Width="60" Height="60" VerticalAlignment="Center" ImageFailed="thumbNail_ImageFailed"
Source="{Binding gameImage,Converter={StaticResource byteToImageConverter}}">
</Image>
</StackPanel>
</StackPanel>
</DataTemplate>
</sdk:DataGrid.RowDetailsTemplate>
转换器:
public class ByteToImageConverter : IValueConverter
{
public BitmapImage ConvertByteArrayToBitMapImage(byte[] imageByteArray)
{
BitmapImage img = new BitmapImage();
using (MemoryStream memStream = new MemoryStream(imageByteArray))
{
img.SetSource(memStream);
}
return img;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
BitmapImage img = new BitmapImage();
if (value != null)
{
img = this.ConvertByteArrayToBitMapImage(value as byte[]);
}
return img;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
但图像没有显示。
我的wcf服务中的方法是这样的:
public List<Games> GamesList()
{
string gmConn = ConfigurationManager.ConnectionStrings["GamesConnectionString"].ConnectionString;
var gamesList = new List<Games>();
using (SqlConnection conn = new SqlConnection(gmConn))
{
string sql = @"Select Name, Developer,Longevity,Distributor,Year,State,Type,graphics, gameplay,sound,general,photo From Games join scores on Games.G_ID=Scores.G_ID";
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
SqlDataReader dr = cmd.ExecuteReader();
if (dr != null)
while (dr.Read())
{
Games game = new Games
{
Name = dr.GetString(0),
developer = dr.GetString(1),
Longevity = dr.GetInt32(2),
Distributor = dr.GetString(3),
Year = dr.GetString(4),
State = dr.GetString(5),
Type = dr.GetString(6),
Graphics = dr.GetDouble(7),
Gameplay = dr.GetDouble(8),
Sound = dr.GetDouble(9),
General = dr.GetDouble(10)
};
if (!dr.IsDBNull(11))
{
byte[] blob = new byte[(dr.GetBytes(11, 0, null, 0, int.MaxValue))];
dr.GetBytes(11, 0, blob, 0, blob.Length);
using (MemoryStream ms = new MemoryStream())
{
ms.Write(blob, 0, blob.Length - 0);
Bitmap bm = (Bitmap)Image.FromStream(ms);
using (MemoryStream msJpg = new MemoryStream())
{
bm.Save(msJpg, ImageFormat.Jpeg);
game.gameImage = msJpg.GetBuffer();
}
}
}
gamesList.Add(game);
}
return gamesList;
}
}
}
在mainPage.xaml.cs中我设置了datagrid的ItemsSource。
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
SampleServiceClient client = new SampleServiceClient();
client.GamesListCompleted += new EventHandler<GamesListCompletedEventArgs>(client_GamesListCompleted);
client.GamesListAsync();
}
void client_GamesListCompleted(object sender, GamesListCompletedEventArgs e)
{
CustomerGrid.ItemsSource = e.Result;
}
}
提前致谢。
答案 0 :(得分:2)
我用你的代码创建了一个简单的测试项目,我无法重新创建你的问题。可能是字节数组已损坏的情况? (只是一个猜测..)
任何方式,您都可以在此处找到并下载测试项目:https://skydrive.live.com/redir?resid=DEB5DDFF6A505390!278我制作了一个带有嵌入式图像的简单项目。我打开那个图像并将其转换为字节数组。然后我用绑定来显示图像。
<强> MainPage.xaml.cs中强>
using System;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Resources;
namespace SilverlightTest
{
public partial class MainPage : UserControl, INotifyPropertyChanged
{
public MainPage()
{
InitializeComponent();
using (var ms = new MemoryStream())
{
StreamResourceInfo sr = Application.GetResourceStream(new Uri("SilverlightTest;component/Koala.jpg", UriKind.Relative));
sr.Stream.CopyTo(ms);
_photo = ms.ToArray();
}
this.DataContext = this;
}
private byte[] _photo;
public byte[] Photo
{
get
{
return _photo;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
}
}
<强> MainPage.xaml中强>
<UserControl x:Class="SilverlightTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SilverlightTest"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<local:ByteToImageConverter x:Name="byteToImageConverter" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Image Width="320" Height="240" VerticalAlignment="Center" Source="{Binding Path=Photo, Converter={StaticResource byteToImageConverter}}" />
</Grid>
</UserControl>
图像作为资源包含在项目中。
<强>更新强>
我看到你在项目中使用了以下代码:
byte[] blob = new byte[(dr.GetBytes(11, 0, null, 0, int.MaxValue))];
dr.GetBytes(11, 0, blob, 0, blob.Length);
using (MemoryStream ms = new MemoryStream())
{
ms.Write(blob, 0, blob.Length - 0);
Bitmap bm = (Bitmap)Image.FromStream(ms);
using (MemoryStream msJpg = new MemoryStream())
{
bm.Save(msJpg, ImageFormat.Jpeg);
game.gameImage = msJpg.GetBuffer();
}
}
此代码无效。您使用GetBuffer()
此代码返回(根据msdn):
创建此流的字节数组或基础 数组,如果未向MemoryStream构造函数提供字节数组 在构建当前实例期间。
要获得正确的数组,请使用MemoryStream类的ToArray()
函数:
byte[] blob = new byte[(dr.GetBytes(11, 0, null, 0, int.MaxValue))];
dr.GetBytes(11, 0, blob, 0, blob.Length);
using (MemoryStream ms = new MemoryStream())
{
ms.Write(blob, 0, blob.Length - 0);
Bitmap bm = (Bitmap)Image.FromStream(ms);
using (MemoryStream msJpg = new MemoryStream())
{
bm.Save(msJpg, ImageFormat.Jpeg);
game.gameImage = msJpg.ToArray();
}
}
并进行了一些重构:
byte[] blob = new byte[(dr.GetBytes(11, 0, null, 0, int.MaxValue))];
dr.GetBytes(11, 0, blob, 0, blob.Length);
using (MemoryStream ms = new MemoryStream(blob))
{
Bitmap bm = (Bitmap)Image.FromStream(ms);
using (MemoryStream msJpg = new MemoryStream())
{
bm.Save(msJpg, ImageFormat.Jpeg);
game.gameImage = msJpg.ToArray();
}
}
更新2 我写了一个小程序来测试你给我的文件(改名为btw文件): SilverlightTestV2.zip
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace ByteTransformer
{
class Program
{
static void Main(string[] args)
{
using (var fs = File.OpenRead("byteArray.dat"))
{
var bm = Image.FromStream(fs);
using (MemoryStream msJpg = new MemoryStream())
{
bm.Save(msJpg, ImageFormat.Jpeg);
using (var ts = File.Create("out.jpg"))
{
var img = msJpg.ToArray();
ts.Write(img, 0, img.Length);
}
}
}
}
}
}
此程序在行var bm = Image.FromStream(fs);
因此我认为或者你给我的文件不包含sql中的实际字节数组(也就是你保存错误)或者sql中的字节数组已损坏。但既然你可以真实地看到图像,我认为你把它保存错了。
答案 1 :(得分:1)
<强>更新强>
将blob直接分配给方法GamesList
中的gameImage-Property应该足够了。其他代码应该没用。
byte[] blob = new byte[(dr.GetBytes(11, 0, null, 0, int.MaxValue))];
dr.GetBytes(11, 0, blob, 0, blob.Length);
game.gameImage = blob;
当您在MemoryStream上调用GetBuffer时,您将获得在MemoryStream的ctor中传递的数组。在您的情况下,您将获得一个空数组或null。我不确定。
<强>初始强>
将ConvertByteArrayToBitMapImage
方法更改为以下
public BitmapImage ConvertByteArrayToBitMapImage(byte[] imageByteArray) {
BitmapImage img = new BitmapImage();
MemoryStream memStream = new MemoryStream(imageByteArray);
img.SetSource(memStream);
return img;
}
使用using
- Statement处理MemoryStream时,流将设置为关闭。因此,BitmapImage无法从使用SetSource
设置的流中读取。