如何从sqlite读回blob到字节数组?

时间:2015-09-22 00:59:24

标签: c# wpf image sqlite bytearray

我有一个OpenFileDialog,允许用户选择单个.png图像。我把它存储到一个属性中:

public byte[] HeroesDBThumbnailImage ...
...
if(OFD.ShowDialog() == true)
{
    HeroesDBThumbnailImage = File.ReadAllBytes(OFD.FileName);
    HeroesDBThumbnailPath = OFD.SafeFileName;
}

在那里设置值后,我将条目插入到DB中,如下所示:

query = ....blahblah...
query += "'" Convert.ToBase64String(HeroesDBThumbnailImage) + "','" + Convert.ToBase64String(HeroesDBFeaturedThumbnailImage) + "'); ";

似乎将数据插入数据库,所以我很高兴。

然后,我把它读回来:

new Hero(
...
HThumbnailImage: (byte[])Row["ThumbnailImage"]
) ...

在XAML中,我有一个图像,用于测试,我绑定到原始字节数组。作为soona,用户从文件选择器中选择一个图像,绑定到该属性的图像源显示该图像。

但是,当我将数据读回另一个属性时,绑定到该字节数组的另一个测试图像不会显示任何内容。所有绑定都是正确的,我试图在运行时进行调试,并且正在读取字节数组,但它看起来与原来的大小不同...原来是899字节,一旦从DB中读回来似乎是940左右...

顺便说一下,SQLite DB中的字段是BLOB。

由于

编辑:根据要求提供额外信息:

好的,所以在我的英雄课程中,我有这个:

public static ObservableCollection<Hero> GetAllHeroes()
{
    ObservableCollection<Hero> Heroes = new ObservableCollection<Hero>();

    try
    {
        var db = new SQLiteDatabase();
        DataTable dt = db.GetDataTable("SELECT * FROM Heroes");
        foreach (DataRow Row in dt.Rows)
        {
            Heroes.Add(new Hero(
                HID: Convert.ToInt32(Row["ID"]),
                HName: Row["Name"].ToString(),
                HGold: Convert.ToInt32(Row["Gold"]),
                HPlatinum: Convert.ToInt32(Row["Platinum"]),
                HDBTag: Row["DBTag"].ToString(),
                HReleaseDate: Convert.ToDateTime(Row["ReleaseDate"]),
                HAvailable: Convert.ToBoolean(Row["Available"]),
                HSale: Convert.ToBoolean(Row["Sale"]),
                HFeatured: Convert.ToBoolean(Row["Featured"]),
                HThumbnailImage: (byte[])Row["ThumbnailImage"],
                HFeaturedThumbnailImage: (byte[])Row["FeaturedThumbnailImage"]
                ));
        }
    }
    catch (Exception err)
    {
        System.Windows.Forms.MessageBox.Show(err.Message);
    }

    return Heroes;
}

与它有关的CTOR是:

public Hero(int HID, string HName, int HGold, int HPlatinum, string HDBTag, DateTime HReleaseDate, bool HAvailable, bool HSale, bool HFeatured, byte[] HThumbnailImage, byte[] HFeaturedThumbnailImage)
{
    ID = HID;
    Name = HName;
    Gold = HGold;
    Platinum = HPlatinum;
    DBTag = HDBTag;
    ReleaseDate = HReleaseDate;
    Available = HAvailable;
    Sale = HSale;
    Featured = HFeatured;
    ThumbnailImage = HThumbnailImage;
    FeaturedThumbnailImage = HFeaturedThumbnailImage;
}

我的viewmodel中有以下属性和函数:

private ObservableCollection<Hero> heroesDBHeroes;
public ObservableCollection<Hero> HeroesDBHeroes
{
    get
    {
        return heroesDBHeroes;
    }
    set
    {
        heroesDBHeroes = value;
        OnPropertyChanged("HeroesDBHeroes");
    }
}
private void HeroesDBAddHeroes()
{
    if(HeroesDBHeroes != null)
    {
        HeroesDBHeroes.Clear();
    }
    HeroesDBHeroes = Hero.GetAllHeroes();
}

HeroesDBAddHeroes在需要之前被调用。

然后我有一个Datagrid,绑定到这个ObservableCollection。 Datagrid代表:

<DataGrid extra:UIElementAttached.IsBubblingMouseWheelEvents="True" ItemsSource="{Binding HeroesDBHeroes}" IsTabStop="False" KeyboardNavigation.TabNavigation="None" Grid.Row="1" IsReadOnly="True">
    <DataGrid.Columns>
        <extra:DataGridTemplateColumn extra:DataGridColumnAttached.CanUserHideColumn="True" AutomationProperties.Name="Image" CanUserSort="True">
            <extra:DataGridTemplateColumn.Header>
                <TextBlock Text="Image" HorizontalAlignment="Center" FontWeight="Bold" FontSize="16" Margin="10,0" />
            </extra:DataGridTemplateColumn.Header>

            <extra:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Name}" />
                        <Image Source="{Binding ThumbnailImage}" />
                    </StackPanel>
                </DataTemplate>
            </extra:DataGridTemplateColumn.CellTemplate>
        </extra:DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

绑定到Name的文本块正确显示,但绑定到ThumbnailImage的图像(也是Hero中的byte [])没有显示任何内容。

1 个答案:

答案 0 :(得分:2)

在存储数据之前,您使用Convert.ToBase64String()对其进行编码,但在读取数据时,您似乎错过了解码部分Convert.FromBase64String(),即:

byte[] base64Data = (byte[])Row["ThumbnailImage"];
string base64String = System.Text.Encoding.ASCII.GetString(base64Data);
byte[] imageData = Convert.FromBase64String(base64String);

PS。您可以在存储和读取时跳过base64编码,并直接存储实际的二进制数据。