Reputation: 984
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
Upvotes: 6
Views: 15516
Reputation: 7336
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));
}
}
Upvotes: 1
Reputation: 6376
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();
}
}
Upvotes: 4
Reputation: 18068
If you want to handle BitmapSource images including cases in which the images' sources are not files, then I recommend copying the pixels' buffer into an array, then storing the array + pixelformat and dimensions metadata (array and metadata can be use to recreate the image).
Upvotes: 0
Reputation: 30636
I'm not sure how the image field type works, however, this might be useful:
Image UriSource and Data Binding
In other words, you may need to use a value converter to convert to/from your db format to your presentation (WPF) format.
Upvotes: 0
Reputation: 18909
make 2 table ,first table contains textbox1's text[maybe "name"] ,textbox2's text[maybe "surname"] and imageId[] ,another table contains file id ,filebytes and file extentions.when you save the aforementioned information with picture. take bytes of image and extention save this. when you get the image inorder to show somewhere,you translate byte to file via its extention http://www.beansoftware.com/ASP.NET-Tutorials/Save-Read-Image-Database.aspx in here for ASP.NET but controls are generally same in .net.(textbox.Text etc.)
private void Button1_Click(object sender, System.EventArgs e)
{
Stream img_strm = upload_file.PostedFile.InputStream;
//Retrieving the length of the file to upload
int img_len = upload_file.PostedFile.ContentLength;
//retrieving the type of the file to upload
string strtype = upload_file.PostedFile.ContentType.ToString();
string strname = txtimgname.Text.ToString();
byte[] imgdata = new byte[img_len];
int n = img_strm.Read(imgdata, 0, img_len);
int result = SaveToDB(strname, imgdata, strtype);}
Upvotes: 0