1

Inserting smaller images work fine. However, when the image file gets bigger than about 2MB, I get an OutOfMemoryException.

I tried with SqlCeUpdatableRecord and a parameterized SqlCeCommand. Using the SqlCeCommand, the exception is raised at ExecuteNonQuery().

With SqlCeUpdatableRecord, the exception is raised at SqlCeUpdatableRecord.SetBytes().

I’ve tried increasing buffer size and temp file size without it seeming to have an effect. I've debugged with GetTotalMemory and there seems to be plenty of resources available.

Any tips would be highly appreciated.

The SQL Server CE database is synchronized with a main SQL Server database and handling images as separate files would introduce a truckload of other issues. The solution has worked fine for years as most WM handhelds only capture images at 5MP or less. However, newer models with support for 8MP images is causing issues.

Here is a simplified version of the SqlCeUpdateblRecord implementation:

System.Data.SqlServerCe.SqlCeUpdatableRecord newRecord = base.CreateRecord();
newRecord["ImageId"] = ImageId;
newRecord["ImageType"] = ImageType;
//64kb buffer (Have tested with different buffer sizes (up to 8MB)
newRecord.SetBytesFromFile("ImageFull", ImageFullFileName, 65536);
newRecord["ImageThumb"] = ImageThumb;
newRecord["ImageDate"] = ImageDate;
base.Insert(newRecord); 

.....
public static void SetBytesFromFile(this SqlCeUpdatableRecord obj, string name, string filename, int buffersize)
{
    int _column = obj.GetOrdinal(name);
    byte[] buffer = new byte[buffersize];            
    int bytesread;
    long offset = 0;

    using (FileStream fs = new FileStream(filename,FileMode.Open))
    {
        bytesread = fs.Read(buffer, 0, buffersize);

        while (bytesread > 0)
        {
            //This will raise OutOfMemoryException for imagefiles larger than appx. 2mb, regardless of buffersize      
            obj.SetBytes(_column, offset, buffer, 0, bytesread);                    
            offset = offset + (long)bytesread;
            bytesread = fs.Read(buffer, 0, buffersize);           
        }
    }
}

Here is a simplified version of the paramterized query:

using (var cmdInsert = new SqlCeCommand("INSERT INTO [Image_CF] ( [ImageId], [ImageType], [ImageFull], [ImageThumb], [ImageDate]) VALUES " +
                                                   " ( @ImageId, @ImageType, @ImageFull, @ImageThumb, @ImageDate)"))
{
    cmdInsert.Connection = Database.IrisPdaConnection;

    cmdInsert.Parameters.Add("@ImageId", System.Data.SqlDbType.Int).Value = ImageId;
    cmdInsert.Parameters.Add("@ImageType", System.Data.SqlDbType.NVarChar).Value = ImageType;
    cmdInsert.Parameters.Add("@ImageFull", System.Data.SqlDbType.Image).Value = GetFileAsBytes(ImageFullFileName);
    cmdInsert.Parameters.Add("@ImageThumb", System.Data.SqlDbType.Image).Value = ImageThumb;
    cmdInsert.Parameters.Add("@ImageDate", System.Data.SqlDbType.NVarChar).Value = ImageDate;

    // OutOfMemoryException for images larger than appx. 2MB
    cmdInsert.ExecuteNonQuery();
}

public byte[] GetFileAsBytes(string filename)
{
   FileStream fs;
   byte[] result;

   using (fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
   {
        // a byte array to read the image
        result = new byte[fs.Length];     
        fs.Read(result, 0, System.Convert.ToInt32(fs.Length));  
   }

   return result; 
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Havad Ostgaard
  • 101
  • 1
  • 9
  • Do you really need to store images in db? This is very bad practice. Can you post code that you use? Are you trying to store Bitmaps? – Alexander R. Apr 11 '15 at 17:30
  • Thanks Alexander. I've updated the post with code examples. The images are jpg captured by the built-in camera. – Havad Ostgaard Apr 12 '15 at 09:28
  • Wonder if you could use SqlCeUpdateableRecord, add say 1 MB of data, insert, and find the row, and add more data to the column? Also, lower the resolution of the camera, and consider saving to the file syste,.. Also, what build of the SQL CE engine is used? Some image column related hotfixes are available – ErikEJ Apr 12 '15 at 09:41
  • Thanks for the hotfix tip Erik. I will investigate this and report back if this helps. Reducing resolution is last resort (We recommend our users to purchase these newer models with better spec :/) – Havad Ostgaard Apr 13 '15 at 08:50
  • I applied hotfix 6 (3.5.8088.0) which is the latest build with device assemblies. No improvement I'm afraid. – Havad Ostgaard Apr 13 '15 at 16:07
  • I have decided to downscale the images as a workaround for the time being. Will leave the case open in the hope that someone else has managed to crack this one.. – Havad Ostgaard Apr 14 '15 at 15:00

0 Answers0