Skip to content

Instantly share code, notes, and snippets.

@vurdalakov
Last active May 20, 2023 11:18
Show Gist options
  • Save vurdalakov/00d9471356da94454b372843067af24e to your computer and use it in GitHub Desktop.
Save vurdalakov/00d9471356da94454b372843067af24e to your computer and use it in GitHub Desktop.
SixLabors.ImageSharp extensions: convert Image<TPixel> to byte array and System.Drawing.Bitmap etc.
namespace Vurdalakov
{
using System;
using System.IO;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
public static class ImageSharpExtensions
{
public static Byte[] ToArray<TPixel>(this Image<TPixel> image, IImageFormat imageFormat) where TPixel : unmanaged, IPixel<TPixel>
{
using (var memoryStream = new MemoryStream())
{
var imageEncoder = image.GetConfiguration().ImageFormatsManager.FindEncoder(imageFormat);
image.Save(memoryStream, imageEncoder);
return memoryStream.ToArray();
}
}
public static System.Drawing.Bitmap ToBitmap<TPixel>(this Image<TPixel> image) where TPixel : unmanaged, IPixel<TPixel>
{
using (var memoryStream = new MemoryStream())
{
var imageEncoder = image.GetConfiguration().ImageFormatsManager.FindEncoder(PngFormat.Instance);
image.Save(memoryStream, imageEncoder);
memoryStream.Seek(0, SeekOrigin.Begin);
return new System.Drawing.Bitmap(memoryStream);
}
}
public static Image<TPixel> ToImageSharpImage<TPixel>(this System.Drawing.Bitmap bitmap) where TPixel : unmanaged, IPixel<TPixel>
{
using (var memoryStream = new MemoryStream())
{
bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
memoryStream.Seek(0, SeekOrigin.Begin);
return Image.Load<TPixel>(memoryStream);
}
}
}
}
@vurdalakov
Copy link
Author

vurdalakov commented May 17, 2020

Fixed error CS8377: The type 'TPixel' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'TPixel' in the generic type or method 'Image'

@sengiv
Copy link

sengiv commented May 10, 2022

Very helpful code, especially for ImageSharp newbies. Thanks!
Is TPixel needed? I didn't know how to call ToImageSharpImage<TPixel>, so i removed it & it works fine.
Please explain the need for TPixel.
Method below without TPixel works aswell.


        public static Image ToImageSharpImage(System.Drawing.Bitmap bitmap)
        {
            using (var memoryStream = new MemoryStream())
            {
                bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);

                memoryStream.Seek(0, SeekOrigin.Begin);

                return Image.Load(memoryStream, new JpegDecoder());
            }
        }

@snechaev
Copy link

snechaev commented Jul 5, 2022

Just as a side note: the MSDN tells us that when we creating an image from a stream, we need to keep this stream alive during the whole life time of the image. See Remarks section of https://docs.microsoft.com/en-us/dotnet/api/system.drawing.bitmap.-ctor?view=dotnet-plat-ext-6.0#system-drawing-bitmap-ctor(system-io-stream). The current version of code works fine in my experiments, but in case if someone will got some strange errors when using the converted image, the disposed stream may be the reason.
On the other hand, the Dispose for MemoryStream does nothing (https://docs.microsoft.com/en-us/dotnet/api/system.io.memorystream?view=net-6.0), so if Image keeps reference to the stream, all should works fine.

@seankearon
Copy link

I agree with @snechaev - disposing of the stream causes an exception when converting from ImageSharp to System.Drawing.Bitmap. I use the following:

    public static Bitmap ImageSharpToBitmap(this SixLabors.ImageSharp.Image img)
    {
        if (img == null) return new Bitmap(0, 0);
        var stream = new MemoryStream();
        img.Save(stream, BmpFormat.Instance);
        stream.Position = 0;
        return  new Bitmap(stream);
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment