how to insert an image into a database using WPF

13,134

Solution 1

The way we do it is to store the images as blobs in the database (they're fairly small images, 4-500k, so storing them in the db shouldn't cause any perf problems), retreive them as byte arrays, and then use a ValueConverter to convert from byte[] to BitMap. The XAML for the image control looks like this:

<Image Source="{Binding Path=RawImageData, 
                        Converter={StaticResource ByteArrayToBitmapImageConverter},
                        Mode=OneWay}" />

The property we bind to in the ViewModel is simply a byte[] like this;

private byte[] _rawImageData;
public byte[] RawImageData
{
    get { return _rawImageData; }
    set
    {
        if (value != _rawImageData)
        {
            _rawImageData = value;
            NotifyPropertyChanged("RawImageData");
        }
    }
}

And then the ValueConverte looks like this;

    public class ByteArrayToBitmapImageConverter : IValueConverter
    {
      public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
      {
        var rawImageData = value as byte[];
        if (rawImageData == null)
          return null;

        var bitmapImage = new System.Windows.Media.Imaging.BitmapImage();
        using (var stream = new MemoryStream(rawImageData))
        {
          bitmapImage.BeginInit();
          bitmapImage.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
          bitmapImage.CacheOption = BitmapCacheOption.Default;
          bitmapImage.StreamSource = stream;
          bitmapImage.EndInit();
        }
        return bitmapImage;
      }

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
     {
       throw new NotImplementedException();
     }
   }

Solution 2

Below a way of how to store/retrieve images in a database using Linq to SQL in WPF.

Database

It's recommended to store the images in separate tables. Create the table where to store your images,

CREATE TABLE UploadedImage(
 [ImageID] [int] IDENTITY(1,1) NOT NULL,
 [ImageName] [varchar](100) NOT NULL,
 [ImageContent] [image] NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

Data access layer using Linq 2 SQL

In Visual Studio add a new item of type LINQ to SQL Classes (.dbml) and lets call it MyDataContext. Use Server Explorer in VS, connect to your database and drag the table of your images UploadedImage to the .dbml design area. Save the MyDataContext file Ctrl + S.

XAML

<TextBox x:Name="ImagePath" />
<Button x:Name="BrowseButton" Content="..." Click="BrowseButton_OnClick"/>
<Button x:Name="SaveButton" Content="Save" Click="SaveButton_OnClick"/>
<Button x:Name="LoadButton" Content="Load" Click="LoadButton_OnClick" />
<Image x:Name="MyImage" >
    <Image.Source>
        <BitmapImage UriSource="{Binding ElementName=ImagePath, Path=Text}" />
    </Image.Source>
</Image>

Code behind

private byte[] _imageBytes = null;

// Browse for an image on your computer
private void BrowseButton_OnClick(object sender, RoutedEventArgs e)
{
    var dialog = new OpenFileDialog
    {
        CheckFileExists = true,
        Multiselect = false,
        Filter = "Images (*.jpg,*.png)|*.jpg;*.png|All Files(*.*)|*.*"
    };

    if (dialog.ShowDialog() != true) { return; }

    ImagePath.Text = dialog.FileName;
    MyImage.Source = new BitmapImage(new Uri(lImagePath.Text));

    using (var fs = new FileStream(ImagePath.Text, FileMode.Open, FileAccess.Read))
    {
        _imageBytes = new byte[fs.Length];
        fs.Read(imgBytes, 0, System.Convert.ToInt32(fs.Length));
    }
}

// Save the selected image to your database
private void SaveButton_OnClick(object sender, RoutedEventArgs e)
{
    if (!String.IsNullOrEmpty(ImagePath.Text))
    {
        var db = new MyDataContext();
        var uploadedImg = new UploadedImage
        {
            ImageID = 0,
            ImageContent = _imageBytes,
            ImageName = ImagePath.Text
        };

        db.UploadedImages.InsertOnSubmit(uploadedImg);
        db.SubmitChanges();
    }
}

// Load an image from the database
private void LoadButton_OnClick(object sender, RoutedEventArgs e)
{
    // Load 1 image from the database and display it
    var db = new ImageInDatabaseDataContext();
    var img = (from el in db.UploadedImages
        select el).FirstOrDefault();


    if (img != null)
    {
        // Display the loaded image
        ImageFile.Source = new BitmapImage(new Uri(img.ImageName));
    }
}
Share:
13,134
femi
Author by

femi

Updated on June 13, 2022

Comments

  • femi
    femi almost 2 years

    I have a WPF question.

    I have 2 textboxes and an image control in a WPF Form. The image control has an image in it.

    I want to insert the contents of each of the text boxes and the image in the 3 separate columns in an SQL database. The text boxes feed into varchar columns while the image itself is loaded into a column with datatype image.

    How can I do this?

    Thanks

  • femi
    femi about 14 years
    thanks for this...its a step in the right direction.. Are there any examples where i can use WPF data bindings to do this? how will i manage field level validations errors in the above scenario? i am using SQL Compact as the database. From what i see i have to manaually map the contents of each control to the databaase , possibly in the method SaveToDB. Is there any other neater or cleaner way to achieve my aim, possibly using collectionviewsource or LINQ TO SQL? Thanks
  • ibrahimyilmaz
    ibrahimyilmaz about 14 years
    maybe this url ll be good for you aneef.net/2009/01/16/…