The following error occurs after the server has been up for a couple of days with employees editing images during the day, then the error stops them from doing their job. Any help would be appreciated.
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Buffers.ConfigurableArrayPool`1.Rent(Int32 minimumLength)
at SixLabors.Memory.ArrayPoolMemoryAllocator.Allocate[T](Int32 length, AllocationOptions options)
at SixLabors.ImageSharp.Memory.MemoryAllocatorExtensions.Allocate2D[T](MemoryAllocator memoryAllocator, Int32 width, Int32 height, AllocationOptions options)
at SixLabors.ImageSharp.Image.CreateUninitialized[TPixel](Configuration configuration, Int32 width, Int32 height, ImageMetaData metadata)
at SixLabors.ImageSharp.Formats.Jpeg.JpegDecoderCore.PostProcessIntoImage[TPixel]()
at SixLabors.ImageSharp.Formats.Jpeg.JpegDecoderCore.Decode[TPixel](Stream stream)
at SixLabors.ImageSharp.Formats.Jpeg.JpegDecoder.Decode[TPixel](Configuration configuration, Stream stream)
at SixLabors.ImageSharp.Image.Decode[TPixel](Stream stream, Configuration config)
at SixLabors.ImageSharp.Image.<>c__DisplayClass55_0`1.<Load>b__0(Stream s)
at SixLabors.ImageSharp.Image.WithSeekableStream[T](Configuration config, Stream stream, Func`2 action)
at SixLabors.ImageSharp.Image.Load[TPixel](Configuration config, Stream stream, IImageFormat& format)
at SixLabors.ImageSharp.Image.Load[TPixel](Configuration config, Stream stream)
at SixLabors.ImageSharp.Image.Load[TPixel](Stream stream)
at SixLabors.ImageSharp.Image.Load(Stream stream)
Hi @wwlgray
I'm afraid it will be very difficult, if not impossible to diagnose any potential issues without the required information as described in the issue template.
If you could please.
I suspect the issue will lie in the improper disposal of images after use (_since we test our own internal code for memory reclamation_) but without a sample I cannot confirm this.
This has two possible causes:
Ok, we have started looking at this. We are running on AZURE PaaS. The following is the version we have stayed with and upgrading right now is not an option. Our production environment scales memory on an as needed basis but is never below 32gb. Code example is below the image. If you need more please let me know.
[cid:c702ed1e-c6d5-484f-9da5-018ce3f2585d]
Calling Function
[HttpPost("api/[controller]/{contractId}/imageedit")]
public async Task
{
if (model.Id == Guid.Empty)
{
throw new ArgumentException(nameof(model.Id));
}
var physicalAsset = await _storageUtility.DownloadAssetAsync(model.Id);
model.SourceStream = physicalAsset.ContentsStream;
using (var destinationStream = new MemoryStream())
{
ImageEditUtility.TransformImage(model, destinationStream);
if (model.IsSave)
{
var assetRecord = await _assetService.FindByIdAsync(model.Id);
bool setThumbs = false;
Guid assetType = assetRecord.AssetTypeId;
switch (model.Tool)
{
// Ww will never overwrite core images, figure out destination type
case ImageTool.Face:
assetType = EntityConstants.AssetType_Face;
break;
case ImageTool.Plate:
assetType = EntityConstants.AssetType_Plate;
break;
case ImageTool.Make:
assetType = EntityConstants.AssetType_Make;
break;
default:
if (assetType == EntityConstants.AssetType_Front1)
assetType = EntityConstants.AssetType_OverrideFront1;
else if (assetType == EntityConstants.AssetType_Front2)
assetType = EntityConstants.AssetType_OverrideFront2;
else if (assetType == EntityConstants.AssetType_Rear1)
assetType = EntityConstants.AssetType_OverrideRear1;
else if (assetType == EntityConstants.AssetType_Rear2)
assetType = EntityConstants.AssetType_OverrideRear2;
model.IsPrimaryImage = true;
setThumbs = true;
break;
}
var existingAsset = _assetService.All().SingleOrDefault(x => x.AssetTypeId == assetType
&& x.AssetDescriptorTypeId ==
EntityConstants
.AssetDescriptorType_OriginalId
&& x.EventId == assetRecord.EventId);
if (existingAsset != null)
{
// The asset we want to write already exists, overwrite it in storage.
await _assetService.UpdateAsync(existingAsset);
await _storageUtility.UploadAssetAsync(existingAsset.Id, destinationStream, setThumbs);
}
else
{
var newAsset = new Asset()
{
EventId = assetRecord.EventId,
AssetTypeId = assetType,
AssetDescriptorTypeId = EntityConstants.AssetDescriptorType_OriginalId
};
var assetId = await _assetService.AddAsync(newAsset);
// Save file
await _storageUtility.UploadAssetAsync(assetId, destinationStream, setThumbs);
}
}
else
{
//Need to set the assetType so we can crop out the info bar from all the filters.
var assetRecord = await _assetService.FindByIdAsync(model.Id);
Guid assetType = assetRecord.AssetTypeId;
if (assetType != EntityConstants.AssetType_Face && assetType != EntityConstants.AssetType_Make &&
assetType != EntityConstants.AssetType_Plate)
model.IsPrimaryImage = true;
}
model.Image = destinationStream.ToArray();
}
physicalAsset.Dispose();
physicalAsset = null;
return Ok(model);
}
Backend Utility Class
public static void TransformImage(ImageEditModel imageEdit, MemoryStream destinationStream)
{
if (destinationStream == null)
{
throw new ArgumentNullException(nameof(destinationStream));
}
var sourceImage = Image.Load(imageEdit.SourceStream);
var blur = imageEdit.History.Where(h => h.Tool == ImageTool.Blur).FirstOrDefault();
bool filtersOnly = imageEdit.Tool == ImageTool.Overwrite;
// Undo is first
if (imageEdit.IsUndo && imageEdit.History.Count > 0)
{
// Remove last entered history item
imageEdit.History.RemoveAt(imageEdit.History.Count - 1);
}
//lets do all of the cropping and blur
//put in a for each because we have to step through them all.
//Only if there are any
if (!filtersOnly)
{
foreach (var item in imageEdit.History.Where(h => h.Tool == ImageTool.Blur || h.Tool == ImageTool.Zoom))
{
sourceImage = ApplyTool(sourceImage, item.StartRect(), item.CropRect(), item.Tool);
}
}
Rectangle startRect = new Rectangle(0, 0, imageEdit.DispWidth, imageEdit.DispHeight);
if (imageEdit.IsUndo && imageEdit.History.Any())
{
// Resize image to fix canvas before applying filters
sourceImage.Mutate(x => x.Resize(startRect.Width, startRect.Height));
// Rollback image edit values and apply previous filters
var item = imageEdit.History.Last();
imageEdit.Brightness = item.Brightness;
imageEdit.Contrast = item.Contrast;
imageEdit.Hue = item.Hue;
imageEdit.Sharpen = item.Sharpen;
imageEdit.CropHeight = item.CropRect().Height;
imageEdit.CropStartX = item.CropRect().X;
imageEdit.CropStartY = item.CropRect().Y;
imageEdit.CropWidth = item.CropRect().Width;
imageEdit.IsPrimaryImage = item.isPrimary;
double ratioHeight = (double)sourceImage.Height / startRect.Height;
sourceImage = ApplyFilter(sourceImage, imageEdit.Tool, imageEdit.Brightness, imageEdit.Contrast, imageEdit.Hue, imageEdit.Sharpen,imageEdit.IsPrimaryImage,ratioHeight);
}
else if (imageEdit.Tool != 0)
{
Rectangle cropRect = new Rectangle(imageEdit.CropStartX, imageEdit.CropStartY, imageEdit.CropWidth, imageEdit.CropHeight);
if (!filtersOnly)
{
sourceImage = ApplyTransformImage(sourceImage, startRect, cropRect, imageEdit.Tool,
imageEdit.Brightness, imageEdit.Contrast, imageEdit.Hue, imageEdit.Sharpen,false,imageEdit.IsPrimaryImage);
}
else if(filtersOnly && blur != null)
{
Rectangle zoomRect = new Rectangle(sourceImage.Bounds().X,sourceImage.Bounds().Y,
sourceImage.Bounds().Width,sourceImage.Bounds().Height);
var imageEditList = imageEdit.History.Where(h => h.Tool == ImageTool.Blur || h.Tool == ImageTool.Zoom).ToList();
foreach (var item in imageEditList)
{
if (item.Tool.Equals(ImageTool.Zoom))
{
Rectangle sourceRec = zoomRect;
//get the ratios
double ratioWidth = (double)sourceRec.Width / item.StartRect().Width;
double ratioHeight = (double)sourceRec.Height / item.StartRect().Height;
//Have to shift left on the selection a bit based on ratio.
int leftShift = 15 * (int)Math.Round((decimal)ratioWidth, 0);
//lets get the projection
zoomRect.X += (int)Math.Round((double)(item.CropRect().X * ratioWidth) - leftShift, 0);
zoomRect.Y += (int)Math.Round((double)(item.CropRect().Y * ratioHeight), 0);
zoomRect.Width = (int)Math.Round((double)(item.CropRect().Width * ratioWidth), 0);
zoomRect.Height = (int)Math.Round((double)(item.CropRect().Height * ratioHeight), 0);
}
else
{
Rectangle sourceRec = sourceImage.Bounds();
Rectangle zoomRectangle = zoomRect;
//get the ratios
double ratioWidth = (double)zoomRectangle.Width / item.StartRect().Width;
double ratioHeight = (double)zoomRectangle.Height / item.StartRect().Height;
//Have to shift left on the selection a bit based on ratio.
int leftShift = 15 * (int)Math.Round((decimal)ratioWidth, 0);
//lets get the projection
sourceRec.X = zoomRectangle.X + (int)Math.Round((double)(item.CropRect().X * ratioWidth) - leftShift, 0);
sourceRec.Y = zoomRectangle.Y + (int)Math.Round((double)(item.CropRect().Y * ratioHeight), 0);
sourceRec.Width = (int)Math.Round((double)(item.CropRect().Width * ratioWidth), 0);
sourceRec.Height = (int)Math.Round((double)(item.CropRect().Height * ratioHeight), 0);
sourceImage.Mutate(x => x.GaussianBlur((float)50.5, sourceRec));
}
}
sourceImage = ApplyFilter(sourceImage, imageEdit.Tool, imageEdit.Brightness, imageEdit.Contrast, imageEdit.Hue, imageEdit.Sharpen, imageEdit.IsPrimaryImage, 0.0);
}
else
{
// On overwrite, no resize
sourceImage = ApplyFilter(sourceImage, imageEdit.Tool, imageEdit.Brightness, imageEdit.Contrast, imageEdit.Hue, imageEdit.Sharpen, imageEdit.IsPrimaryImage, 0.0);
}
if (imageEdit.Tool != ImageTool.Overwrite && imageEdit.Tool != ImageTool.Face &&
imageEdit.Tool != ImageTool.Plate && imageEdit.Tool != ImageTool.Make)
{
ImageHistoryModel icm = new ImageHistoryModel
{
cropRect = CleanRectangle(cropRect),
startRect = CleanRectangle(startRect),
Brightness = imageEdit.Brightness,
Contrast = imageEdit.Contrast,
Hue = imageEdit.Hue,
Tool = imageEdit.Tool,
Sharpen = imageEdit.Sharpen,
isPrimary = imageEdit.IsPrimaryImage
};
imageEdit.History.Add(icm);
}
}
else
{
// Resize image to fix canvas before sending back unalter image
sourceImage.Mutate(x => x.Resize(startRect.Width, startRect.Height));
}
sourceImage.SaveAsJpeg(destinationStream);
destinationStream.Seek(0, SeekOrigin.Begin);
imageEdit.SourceStream.Dispose();
imageEdit.SourceStream = null;
sourceImage.Dispose();
sourceImage = null;
if (!imageEdit.IsSave)
{
// Reset Tool for next edit
imageEdit.Tool = 0;
}
}
private static Image<Rgba32> ApplyTransformImage(Image<Rgba32> sourceImage, Rectangle startRect, Rectangle cropRect, ImageTool tool, int bright, int cont, int hue, int sharp, bool isHistory = false,bool isPrimary = false)
{
if (tool == ImageTool.Blur || tool == ImageTool.Zoom)
{
sourceImage = ApplyTool(sourceImage, startRect, cropRect, tool);
}
if (!isHistory)
{
// Resize image to fix canvas before applying filters
//Required because the Zoom tool will change the size of the image if it is not bigger than the canvas.
if (startRect.Height <= 400) startRect.Height = 400;
if (startRect.Width <= 600) startRect.Width = 600;
//used for the transform
double ratioHeight = (double)sourceImage.Height / startRect.Height;
sourceImage.Mutate(x => x.Resize(startRect.Width, startRect.Height));
sourceImage = ApplyFilter(sourceImage, tool, bright, cont, hue, sharp, isPrimary, ratioHeight);
}
return sourceImage;
}
From: Anton Firszov @.>
Sent: Thursday, March 18, 2021 9:41 AM
To: SixLabors/ImageSharp *@.>
Cc: Walter Gray @.>; Mention @.*>
Subject: Re: [SixLabors/ImageSharp] MemoryException when loading an image (#1577)
This has two possible causes:
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FSixLabors%2FImageSharp%2Fissues%2F1577%23issuecomment-801934466&data=04%7C01%7C%7C1c5c2d4464f5466712a408d8ea137a4b%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637516716665036634%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=iEhxOGGGTSP2z6l4IGPvfnDmNGm8WHq7xlUXXvq3Fqk%3D&reserved=0, or unsubscribehttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAB3PH5R2HJGTWOJRCHCUTYTTEH7HBANCNFSM4ZLMEOXA&data=04%7C01%7C%7C1c5c2d4464f5466712a408d8ea137a4b%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637516716665036634%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=jgy%2Fl7pN6pMVHObYu6FnZ7ynHwL59EW2jerIeGX%2FOTw%3D&reserved=0.
Copied the code into a gist for better reading:
https://gist.github.com/antonfirsov/765dc11a8f83a786bdcd0f453e534004
@wwlgray couple of suggestions:
Diagnosing ideas (to look for issues in more details):
ImageEdit locally in a loop, and check it's impact on memory consumption.Mitigation ideas (based on what I see in the code now):
ApplyTool(....) disposes the image in parameter if it creates a new instanceDispose() (an unexpected exception may escape the manual call!)Thanks for the suggestions and we are also upgrading. I didn't realize how far behind we were. I am bring the application current. I have another programmer looking into using the SimpleGC to see if it helps. I have ran a memory graph and depending on the size of the image, it goes up from 2 to 7 mb with every load of an image. Thanks for your quick response
--Walter
From: Anton Firszov @.>
Sent: Thursday, March 18, 2021 11:03 AM
To: SixLabors/ImageSharp *@.>
Cc: Walter Gray @.>; Mention @.*>
Subject: Re: [SixLabors/ImageSharp] MemoryException when loading an image (#1577)
Diagnosing ideas (to look for issues in more details):
Mitigation ideas (based on the code):
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FSixLabors%2FImageSharp%2Fissues%2F1577%23issuecomment-802000856&data=04%7C01%7C%7Ccb138af9450340304f1d08d8ea1ef3d2%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637516765943830866%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=nGfGENCFqHXgdrtiWG4TlDnpKbhOMIv%2Fp14wEXk8YQ4%3D&reserved=0, or unsubscribehttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAB3PH5SDYREXD4WVGUCG6PDTEII3BANCNFSM4ZLMEOXA&data=04%7C01%7C%7Ccb138af9450340304f1d08d8ea1ef3d2%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637516765943830866%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=XlwLXQyDqoJMPA2tkDLTReFYJ0n56iOnYci0u2Vn7OI%3D&reserved=0.
I have another programmer looking into using the SimpleGC to see if it helps
@wwlgray if you indeed have 32GB, I think this will only help if you work with very large images with really high server load. My best guess is that there is a resource leak (= stream, image or something else left undisposed) and you need to hunt it down. (Or you are indeed using a very old ImageSharp that had some memory leaks internally.)
Let us know if you get stuck. Again: seeing a memory profile would be lifesaving in that case!
Looks like the upgrade took care of most of our issues. We will look into using statements as well. Thanks for your help. I really should have done this through my corporate email and not my personal. lol
Walter Gray
From: Anton Firszov @.>
Sent: Thursday, March 18, 2021 11:14 AM
To: SixLabors/ImageSharp *@.>
Cc: Walter Gray @.>; Mention @.*>
Subject: Re: [SixLabors/ImageSharp] MemoryException when loading an image (#1577)
I have another programmer looking into using the SimpleGC to see if it helps
@wwlgrayhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fwwlgray&data=04%7C01%7C%7C2abc03bc11f94af1356008d8ea207bca%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637516772519254298%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=VHAzdWjCySfCE1aGaumSy7S1MAiaSy%2FDicyV%2FZotisg%3D&reserved=0 if you indeed have 32GB, I think this will only help if you work with very large images with really high server load. My best guess is that there is a resource leak (= stream, image or something else left undisposed) and you need to hunt it down. (Or you are indeed using a very old ImageSharp that had some memory leaks internally.)
Let us know if you get stuck. Again: seeing a memory profile would be lifesaving in that case!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FSixLabors%2FImageSharp%2Fissues%2F1577%23issuecomment-802009170&data=04%7C01%7C%7C2abc03bc11f94af1356008d8ea207bca%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637516772519264248%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=cZJOcivWMgS22suyYY1PUNxhnkRxSghC2qJQsn%2FINK0%3D&reserved=0, or unsubscribehttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAB3PH5W3AHXX5GD37DAMJG3TEIKEFANCNFSM4ZLMEOXA&data=04%7C01%7C%7C2abc03bc11f94af1356008d8ea207bca%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637516772519264248%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=zHsvotk4JkzfmQw4J8lckj1XAdFRYl%2BJLDiaTvCVtQQ%3D&reserved=0.
That's great to hear @wwlgray
I'll close this issue for now than. If you have any others do not hesitate to get in touch.
Thanks guys.
From: James Jackson-South @.>
Sent: Thursday, March 18, 2021 5:47 PM
To: SixLabors/ImageSharp *@.>
Cc: Walter Gray @.>; Mention @.*>
Subject: Re: [SixLabors/ImageSharp] MemoryException when loading an image (#1577)
I'll close this issue for now than. If you have any others do not hesitate to get in touch.
-
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FSixLabors%2FImageSharp%2Fissues%2F1577%23issuecomment-802324704&data=04%7C01%7C%7Cc0f9d55dc60e43b8987408d8ea574f8e%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637517008005594059%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=TJWJTOzdCzCg3FW2xqtNmsumaCIkPIg6%2FA9NUHfK3qA%3D&reserved=0, or unsubscribehttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAB3PH5UIDYKRRCWHGD4H4DLTEJYD5ANCNFSM4ZLMEOXA&data=04%7C01%7C%7Cc0f9d55dc60e43b8987408d8ea574f8e%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637517008005604027%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=tvfQ%2FOdIChh7UFmWm6ad4PzNElmlfv01sWCgBaBQFGc%3D&reserved=0.
Most helpful comment
Looks like the upgrade took care of most of our issues. We will look into using statements as well. Thanks for your help. I really should have done this through my corporate email and not my personal. lol
Walter Gray
From: Anton Firszov @.>
Sent: Thursday, March 18, 2021 11:14 AM
To: SixLabors/ImageSharp *@.>
Cc: Walter Gray @.>; Mention @.*>
Subject: Re: [SixLabors/ImageSharp] MemoryException when loading an image (#1577)
I have another programmer looking into using the SimpleGC to see if it helps
@wwlgrayhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fwwlgray&data=04%7C01%7C%7C2abc03bc11f94af1356008d8ea207bca%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637516772519254298%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=VHAzdWjCySfCE1aGaumSy7S1MAiaSy%2FDicyV%2FZotisg%3D&reserved=0 if you indeed have 32GB, I think this will only help if you work with very large images with really high server load. My best guess is that there is a resource leak (= stream, image or something else left undisposed) and you need to hunt it down. (Or you are indeed using a very old ImageSharp that had some memory leaks internally.)
Let us know if you get stuck. Again: seeing a memory profile would be lifesaving in that case!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FSixLabors%2FImageSharp%2Fissues%2F1577%23issuecomment-802009170&data=04%7C01%7C%7C2abc03bc11f94af1356008d8ea207bca%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637516772519264248%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=cZJOcivWMgS22suyYY1PUNxhnkRxSghC2qJQsn%2FINK0%3D&reserved=0, or unsubscribehttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAB3PH5W3AHXX5GD37DAMJG3TEIKEFANCNFSM4ZLMEOXA&data=04%7C01%7C%7C2abc03bc11f94af1356008d8ea207bca%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637516772519264248%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=zHsvotk4JkzfmQw4J8lckj1XAdFRYl%2BJLDiaTvCVtQQ%3D&reserved=0.