patterncsharpMinor
Fastest image upload into SQL database
Viewed 0 times
imagesqluploadintodatabasefastest
Problem
I am trying to upload an image (screenshot from desktop) to an SQL database as fast as possible. I would like to optimize my current procedure in terms of speed:
```
bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
gfxScreenshot = Graphics.FromImage(bmpScreenshot);
gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy);
byte[] imageBytes = convertImageToByteArray(bmpScreenshot);
MemoryStream mem = new MemoryStream(imageBytes);
using (Bitmap bmp1 = (Bitmap)Image.FromStream(mem))
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
ImageCodecInfo jgpEncoder = codecs[1];
System.Drawing.Imaging.Encoder myEncoder =
System.Drawing.Imaging.Encoder.Quality;
}
using (MemoryStream m = new MemoryStream())
{
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 23L);
myEncoderParameters.Param[0] = myEncoderParameter;
bmp1.Save(m, jgpEncoder, myEncoderParameters);
using (Bitmap bmpLast = (Bitmap)Image.FromStream(m))
{
string query = "UPDATE ScreenCapture SET ScreenCapture=@Image,BroadcastTime=@BroadcastTime WHERE ID = 1";
SqlCommand sqlCommand = new SqlCommand(query, SQLconn);
ImageConverter converter = new ImageConverter();
byte[] beforeUpload = (byte[])converter.ConvertTo(bmpLast, typeof(byte[]));
```
bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
gfxScreenshot = Graphics.FromImage(bmpScreenshot);
gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy);
byte[] imageBytes = convertImageToByteArray(bmpScreenshot);
MemoryStream mem = new MemoryStream(imageBytes);
using (Bitmap bmp1 = (Bitmap)Image.FromStream(mem))
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
ImageCodecInfo jgpEncoder = codecs[1];
System.Drawing.Imaging.Encoder myEncoder =
System.Drawing.Imaging.Encoder.Quality;
}
using (MemoryStream m = new MemoryStream())
{
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 23L);
myEncoderParameters.Param[0] = myEncoderParameter;
bmp1.Save(m, jgpEncoder, myEncoderParameters);
using (Bitmap bmpLast = (Bitmap)Image.FromStream(m))
{
string query = "UPDATE ScreenCapture SET ScreenCapture=@Image,BroadcastTime=@BroadcastTime WHERE ID = 1";
SqlCommand sqlCommand = new SqlCommand(query, SQLconn);
ImageConverter converter = new ImageConverter();
byte[] beforeUpload = (byte[])converter.ConvertTo(bmpLast, typeof(byte[]));
Solution
For graphic part :
I think Gdi++ of .NET framework is very slow.
Mainly the Bitmap() construtor and Save() method.
If it's possible for screenshot, I recommend to use :
Either directly gdi32.dll or (maybe, im not sure that is good idea) direct2d (benefits on hardware acceleration).
For transfert :
For your upload, run the transfert in other thread. (async or Delegate with BeginInvoke).
After it depends on your internet connection speed.
However, i don't understand why you recreate your Bitmap object twice :
Don't reload with Bitmap,
create only one Bitmap for your screenshot, save it with encoding in memory stream and send memory stream to your database. With your memory stream you can get directly byte array with no conversion.
I think Gdi++ of .NET framework is very slow.
Mainly the Bitmap() construtor and Save() method.
If it's possible for screenshot, I recommend to use :
Either directly gdi32.dll or (maybe, im not sure that is good idea) direct2d (benefits on hardware acceleration).
For transfert :
For your upload, run the transfert in other thread. (async or Delegate with BeginInvoke).
After it depends on your internet connection speed.
However, i don't understand why you recreate your Bitmap object twice :
using (Bitmap bmp1 = (Bitmap)Image.FromStream(mem))
using (Bitmap bmpLast = (Bitmap)Image.FromStream(m))Don't reload with Bitmap,
create only one Bitmap for your screenshot, save it with encoding in memory stream and send memory stream to your database. With your memory stream you can get directly byte array with no conversion.
MemoryStream.Read(byte[] buffer, int offset, int count)Code Snippets
using (Bitmap bmp1 = (Bitmap)Image.FromStream(mem))
using (Bitmap bmpLast = (Bitmap)Image.FromStream(m))MemoryStream.Read(byte[] buffer, int offset, int count)Context
StackExchange Code Review Q#43658, answer score: 2
Revisions (0)
No revisions yet.