TL;DR; Images converted to base64string have huge RAM footprint in large object heap.
I have some code in a windows service that consumes our product images uploaded by users, standardizes them into a web-grade format (they will upload 10MB bitmaps), and does some other things like resize them into a square and add whitespace padding.
It then converts them to a base64 string to upload them into our hosting environment via rest. The environment requires it be done this way, i cannot use URLS. When I do this, they get stored on the large object heap and the program's RAM usage skyrockets over time.
How do I get around this issue?
Here is the code,
private void HandleDocuments(IBaseProduct netforumProduct, MagentoClient client, bool isChild)
{
if (netforumProduct.Documents == null) { return; }
for (int idx = 0; idx < netforumProduct.Documents.Count; idx++)
{
JToken document = netforumProduct.Documents[idx]["Document"];
if (document == null) { continue; }
string fileName = document["URL"].ToString();
// Skip photos on child products (the only identifier is part of the url string)
if (fileName.ToLower().Contains("photo") && isChild) { continue; }
using (HttpClient instance = new HttpClient {BaseAddress = client.NetforumFilesBaseAddress})
{
string trimStart = fileName.TrimStart('.');
string base64String;
using (Stream originalImageStream = instance.GetStreamAsync("iweb" + trimStart).Result)
{
using (MemoryStream newMemoryStream = new MemoryStream())
{
using (Image img = Image.FromStream(originalImageStream))
{
using (Image retImg = Utility.Framework.ImageToFixedSize(img, 1200, 1200))
{
retImg.Save(newMemoryStream, ImageFormat.Jpeg);
}
}
newMemoryStream.Position = 0;
byte[] bytes = newMemoryStream.ToArray();
base64String = Convert.ToBase64String(bytes);
}
}
// MediaGalleryEntry is a simple class with a few string properties
MediaGalleryEntry mge = new MediaGalleryEntry
{
label = "Product_" + netforumProduct.Code + "_image_" + idx,
content = new MediaGalleryContent
{
base64_encoded_data = base64String,
name = "Gallery_Image_" + idx
},
file = trimStart
};
this.media_gallery_entries.Add(mge);
}
}
}
Its not the best code ever, probably not highly optimized, but its the best I can do.