49

I am trying to save a bitmap image to database

Bitmap map = new Bitmap(pictureBoxMetroMap.Size.Width, pictureBoxMetroMap.Size.Height);

I created a column imgcontent in the database with datatype binary but my problem is how can I convert this bitmap (map) to binary data?

And how can I retrieve data from database?

I googled it and I found something like this but it didn't work:

byte[] arr;
ImageConverter converter = new ImageConverter();
arr = (byte[])converter.ConvertTo(map, typeof(byte[]));
Ehsan Akbar
  • 6,977
  • 19
  • 96
  • 180

2 Answers2

93

Convert the image to a byte[] and store that in the database.


Add this column to your model:

public byte[] Content { get; set; }

Then convert your image to a byte array and store that like you would any other data:

public byte[] ImageToByteArray(System.Drawing.Image imageIn)
{
    using(var ms = new MemoryStream())
    {
        imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
    
        return ms.ToArray();
    }
}

public Image ByteArrayToImage(byte[] byteArrayIn)
{
     using(var ms = new MemoryStream(byteArrayIn))
     {
         var returnImage = Image.FromStream(ms);

         return returnImage;
     }
}

Source: Fastest way to convert Image to Byte array

var image = new ImageEntity()
{
   Content = ImageToByteArray(image)
};

_context.Images.Add(image);
_context.SaveChanges();

When you want to get the image back, get the byte array from the database and use the ByteArrayToImage and do what you wish with the Image

This stops working when the byte[] gets to big. It will work for files under 100Mb

JensB
  • 6,663
  • 2
  • 55
  • 94
  • 1
    What if I want to save a file whixh exceeds 100MB? How do I tweak the code? – mcfred Jul 30 '18 at 09:28
  • 1
    @bangbang Then I would personally think about storing the file on disk and saving the path to the file in the database instead. – JensB Aug 31 '18 at 12:29
  • 1
    however if you still want to save it in DB, use varbinary(max). limit 2GB. – Adeel Shekhani Sep 12 '18 at 16:43
  • 1
    @AdeelShekhani The problem for me was not that the database would be unable to store it but that EF would time out or take a very long time trying to send it to the database. – JensB Sep 13 '18 at 06:38
0

I suggest using this extension library if you want clean and efficient use of memory for bigger files. This library stores files in smaller chunks.

https://www.nuget.org/packages/Files.EntityFrameworkCore.Extensions

If support file Create, Delete & Get.

public class UserImage : IFileEntity
{
    public Guid Id { get; set; }
    public Guid FileId { get; set; }
    public string Name { get; set; }
    public string MimeType { get; set; }
    public DateTimeOffset TimeStamp { get; set; }
    public Guid? NextId { get; set; }
    public int ChunkBytesLength { get; set; }
    public long TotalBytesLength { get; set; }
    public byte[] Data { get; set; }
}

//Save file chunks from stream to database, you can also save from filePath
var fileDetails = await _context.SaveFileAsync<UserImage>(file.OpenReadStream(), file.FileName, file.ContentType);

//Create Stream and download file chunks from database into this stream.
var stream = new MemoryStream();
await _context.DownloadFileToStreamAsync<UserImage>(id, stream);
sitholewb
  • 309
  • 2
  • 6