DEBUG and RELEASE modeI could load files from memory stream like this prior to version alpha4-48 :
class ImageSharpHelper{
..
..
public void SetImage(Stream file)
{
Client?.Dispose();
Client = new ImageSharp.Image(file);
Mime = Client.CurrentImageFormat.MimeType;
OutPutTypes = ImageOutPutTypes.None;
}
..
..
}
but i noticed the load mechanism changed in version 47 and need to use the Load method. but the stream that imagesharp is now accepting in Load method is FileStream. if i load the image from hashStream that AWS SDK S3 is returning I will get error that the stream is not seekable,
if I load the hashStream into a memoryStream and load it into imagesharp, then i will get an error that the file format is not supported and only bmp, gift and jpg and png is supported.
System.NotSupportedException occurred
HResult=-2146233067
Message=Image cannot be loaded. Available formats:
-ImageSharp.Formats.PngFormat
-ImageSharp.Formats.JpegFormat
-ImageSharp.Formats.GifFormat
-ImageSharp.Formats.BmpFormatSource=ImageSharp
StackTrace:
at ImageSharp.Image.LoadTColor
at ImageSharp.Image.Load(Stream stream)
at xxxx.xxxxx.Image.ImageSharpHelper.d__24.MoveNext() in C:UsersxxxxxxDocumentsVisual Studio 2015Projectsxxxx.xxxxxxsrcxxxxx.xxxxxxxxImageImageSharpHelper.cs:line 123
InnerException:
if I convert the memory stream to byte array, then everything is fine and imagesharp is loading the file with no error.
What is the position of your MemoryStream? I have the feeling it is not at the start?
writing to a memory stream works fine you just need to remember to set stream.Positon = 0; before calling Image.Load(stream) how ever you should not need to do that, I introduced a bug while migrating the code into the static Load method this has been fixed on master.
I'll let you know the package version once its finished building.
1.0.0-alpha5-00049 has this fix in
This bug still exists in 1.0.0-beta0007. The following code to Threshold an image works on Windows and Linux, but removing the commented line breaks (only) Linux with a "Parameter not valid" exception getting thrown on the final "return new Bitmap...":
using (var stream = new MemoryStream())
{
var img2 = new Bitmap(image);
img2.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
stream.Position = 0; // <-- MUST HAVE THIS TO WORK IN LINUX!!!
var myImage = SixLabors.ImageSharp.Image.Load(stream.ToArray());
myImage.Mutate(x => x.Grayscale().BinaryThreshold((float)thresholdValue/255));
using (var resultStream = new MemoryStream())
{
myImage.SaveAsBmp(resultStream);
return new Bitmap(resultStream);
}
}
Why are you mixing ImageSharp and System.Drawing?
The bug is in your code not ours. You鈥檙e calling stream.ToArray() which is where any issues will occur before calling our Load method. Which is hugely wasteful btw.
You鈥檙e also not disposing of either img2 or myImage.
Thanks for the reply, JimBob-- I am mixing the two types because System.Drawing is used elsewhere in my application (.Net Core 3, which natively supports it) but had to crossover into ImageSharp types to use its image filters. This was the way I found that worked, but may not be ideal.
You're correct about my not disposing of resources properly... the code posted was simply meant to show something that "worked" in one OS but not another. I don't understand why "stream.Position=0" would be required for Linux but not Windows. If you think this is as designed, then please disregard. Thanks again.
No worries. You鈥檇 have to take up the position issue with Microsoft. Like I said before you鈥檙e passing us the array not the stream, whatever action has taken place that requires the position change happens before you use our APIs
Regarding interop. We have some code in our unit tests that could be refactored to convert between the two.
@tomahawk1277 test code for wrapping an existing memory buffer as Image<T> without doing copies, could be found here. This is a rather advanced use case though, you have to be familiar with the System.Memory library as well as pixel formats.
A bit simpler but still fast solution: pin the image data using LockBits, wrap the memory area into a Span<TPixel> and use Image.LoadPixelData<TPixel>().
The difference in MemoryStream behavior is strange indeed, but it has nothing to do with ImageSharp.
Thank you, @antonfirsov -- I will use one of these methods instead in order to speed things up. Better yet, I'll probably just convert everything over to ImageSharp from the very get-go and abandon System.Drawing in .NET Core 3 since I need ImageSharp for the image utilities.
Thanks again.
Most helpful comment
1.0.0-alpha5-00049has this fix in