One of the requirements in the application I have been working on lately is to save images to a sql server database. I found snippets of code around the web but nothing that put it all together. So I created a test project to figure out what needed to be done. This is just test code not production ready code.
First I created a simple table to hold the images.
CREATE TABLE [dbo].[TestTable]
(
[ImageId] [int] IDENTITY(1,1) NOT NULL,
[ImageData] [varbinary](max) NULL,
CONSTRAINT [PK_Images] PRIMARY KEY CLUSTERED ([ImageId] ASC)
) ON [PRIMARY]
I created my data model using Linq to SQL and finally a domain service using RIA Services. The first part that I had to figure out was how to convert the byte array into a bitmap so it can be used to set an image control's source property. It turned out to be fairly easy. I wrote a Byte Array to bitmap converter.
public class ByteArrayToBitMapConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var binaryData = (byte[])value;
if (binaryData == null)
{
return null;
}
BitmapImage bitmap = null;
if (IsJpegOrPngImage(binaryData))
{
Stream stream = null;
try
{
stream = new MemoryStream(binaryData);
bitmap = new BitmapImage();
bitmap.SetSource(stream);
}
catch (Exception e)
{
bitmap = null;
}
finally
{
if (stream != null)
{
stream.Dispose();
}
}
}
return bitmap;
}
private static bool IsJpegOrPngImage(byte[] binaryData)
{
if (binaryData.Length > 2)
{
if (binaryData[0].Equals(0XFF) && binaryData[1].Equals(0XD8))
{
return true;
}
if (binaryData[0].Equals(0X89) && binaryData[1].Equals(0X50))
{
return true;
}
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Since I am only dealing with Png and Jpg images I added some logic to the converter to check the first two bytes to make sure that I am trying to convert the right type of image file. The XAML using the converter then looks like this:
<local:ByteArrayToBitMapConverter x:Key="ArrayToBitmap" />
<DataTemplate x:Key="ReadFormStyle">
<StackPanel>
<dataFormToolkit:DataField Label="Image Id">
<TextBlock Text="{Binding ImageId}" />
</dataFormToolkit:DataField>
<dataFormToolkit:DataField Label="Image">
<StackPanel>
<Image Source="{Binding ImageData, Converter={StaticResource ArrayToBitmap}}"
Height="400"
Width="400"
Stretch="None"></Image>
</StackPanel>
</dataFormToolkit:DataField>
</StackPanel>
</DataTemplate>
...
I used some of the code from my previous post about encoding a jpg image but used ImageTools library to be able to do png compression. Next was getting an image from the client's local drive to save to the database. The only challenge that I encountered here was that when using FJCore to resize and encode a jpeg image it created some artifacts so I opted for converting the image to Png and then use Silverlight's ScaleTransform to do the resizing.
void GetLocalImage_Click(object sender, RoutedEventArgs e)
{
var dialog = new OpenFileDialog
{
Filter = "Image files(*.jpg;*.jpeg;*.png)|*.jpg;*.jpeg;*.png|All Files (*.*)|*.*"
,
FilterIndex = 1
};
if (dialog.ShowDialog() == true)
{
using (Stream fileStream = dialog.File.OpenRead())
{
WriteableBitmap bitmap = new WriteableBitmap(1, 1);
bitmap.SetSource(fileStream);
double newWidth = 300;
double newHeight = bitmap.PixelHeight * (newWidth / bitmap.PixelWidth);
var tempImage = new System.Windows.Controls.Image();
tempImage.Source = bitmap;
WriteableBitmap resize = ResizeWriteableBitmap(bitmap, newWidth, newHeight, tempImage);
Stream pngCompressed = GetPngStream(resize);
pngCompressed.Seek(0, SeekOrigin.Begin);
byte[] binary = new Byte[pngCompressed.Length];
long bRead = pngCompressed.Read(binary, 0, (int)pngCompressed.Length);
var imageRecord = dataForm.CurrentItem as TestTable;
imageRecord.ImageData = binary;
};
}
}
You can download a zip file of my test project here:
ImageTest.zip (2.29 mb)
Of course you will need to change the connection string to your local instance of SQL Server.
cd359245-dc13-4b7a-8190-37953f1b5804|4|3.8
Blog, BlogEngine.NET
silverlight, ria services, image