Storing System.Bitmap in documents

88 views
Skip to first unread message

Sean Kearon

unread,
Apr 28, 2012, 4:22:55 AM4/28/12
to rav...@googlegroups.com
I have a few small images in one of my types.  Is there a way to store these inline in the document in RavenDB or are attachments the only way?

Mauro Servienti

unread,
Apr 28, 2012, 5:45:33 AM4/28/12
to rav...@googlegroups.com
if you don't care about perf issues of loading big docs you can store the byte[] that represents the image.

.m
_____________________
It's all about trust...

From: Sean Kearon
Sent: 28/04/2012 10:23
To: rav...@googlegroups.com
Subject: [RavenDB] Storing System.Bitmap in documents

Sean Kearon

unread,
Apr 28, 2012, 6:54:43 AM4/28/12
to rav...@googlegroups.com
Thanks Mauro.  Yes, I understand the performance issues.  However, it seems sensible for me right now to avoid attachments for these images.  The images are guaranteed to be small as they are compressed by the app when the user loads then up.  

In case anyone else is interested, I've done this by registering a custom JSON serialiser to convert the images to byte[]:

// Serialise images inline with the document by default.  
store.Conventions.CustomizeJsonSerializer = serializer => serializer.Converters.Add(new AtlanticImageConverter());

/// <summary>
///   Serialises <see cref="Image" /> properties as a <see cref="byte" /> array.
/// </summary>
public class AtlanticImageConverter : JsonConverter
{
   #region Methods
 
   public override bool CanConvert(Type objectType)
   {
      return typeof (Image).IsAssignableFrom(objectType);
   }
 
   public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
   {
      if (reader.TokenType == JsonToken.Null)
      {
         if (IsNullableType(objectType))
         {
            return null;
         }
         throw new Exception(string.Format("Cannot convert null value to {0}.", objectType));
      }
 
      byte[] numArray;
      switch (reader.TokenType)
      {
         case JsonToken.Bytes:
            numArray = reader.Value as byte[];
            break;
         case JsonToken.String:
            numArray = Convert.FromBase64String(reader.Value.ToString());
            break;
         default:
            throw new Exception(string.Format("Unexpected token parsing binary. Expected Bytes, got {0}.", reader.TokenType));
      }
      return ToImage(numArray);
   }
 
   public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
   {
      if (value == null)
      {
         writer.WriteNull();
      }
      var image = value as Image;
      var bytes = ToBlob(image);
      writer.WriteValue(bytes);
   }
 
   private bool IsNullableType(Type t)
   {
      return (t.IsGenericType) && t.GetGenericTypeDefinition() == typeof (Nullable<>);
   }
 
   private byte[] ToBlob(Image image)
   {
      if (image != null)
      {
         using (var stream = new MemoryStream())
         {
            image.Save(stream, ImageFormat.Png);
            stream.Seek(0, SeekOrigin.Begin);
 
            var reader = new BinaryReader(stream);
            var buffer = new byte[stream.Length];
 
            reader.Read(buffer, 0, buffer.Length);
            return buffer;
         }
      }
      return null;
   }
 
   private Bitmap ToImage(byte[] blob)
   {
      if (blob == null || blob.Length == 0) return null;
      using (var stream = new MemoryStream(blob))
      {
         return new Bitmap(Image.FromStream(stream));
      }
   }
 
   #endregion
}

Sean Kearon

unread,
Apr 28, 2012, 8:26:45 AM4/28/12
to rav...@googlegroups.com
Hmmm, having run that over some user data it doesn't seem like such a good idea after all.  Now looking at attachments instead...


On Saturday, 28 April 2012 10:45:33 UTC+1, Mauro Servienti wrote:

Mauro Servienti

unread,
Apr 28, 2012, 10:38:54 AM4/28/12
to rav...@googlegroups.com

It is not a good idea :-) attachments are there for a reason ;-)

 

.m

Itamar Syn-Hershko

unread,
Apr 28, 2012, 1:28:37 PM4/28/12
to rav...@googlegroups.com
Never a good idea. Use Attachments or some cloud service.
Reply all
Reply to author
Forward
0 new messages