1

The documentation for SixLabors ImageSharp is very limited, and most google searches leads to GitHub, which is not very helpful.

How can I upload a jpg, .Mutate it with transparent padding and save it as a png with transparency?

This is the code I have so far. If the uploaded image is a png, transparent padding works, but jpgs get black padding:

private static void ResizeAndSavePhoto(Image<Rgba32> img, string path, int squareSize)
{
    Configuration.Default.ImageFormatsManager.SetEncoder(PngFormat.Instance, new PngEncoder()
    {
        ColorType = PngColorType.RgbWithAlpha
    });
    img.Mutate(x =>
        x.Resize(new ResizeOptions
        {
            Size = new Size(squareSize, squareSize),
            Mode = ResizeMode.Pad
        }).BackgroundColor(new Rgba32(255, 255, 255, 0))
        );
    img.Save(path);
    return;
}

.SaveAsPng() takes a filestream, but I have an Image<Rgba32> and a path...

Stian
  • 1,522
  • 2
  • 22
  • 52

2 Answers2

2

You can explicitly save as a png via SaveAsPng, set the path extensions to .png, or pass an IImageEncoder to the Save methods.

You'll find API docs at https://docs.sixlabors.com/api/index.html

private static void ResizeAndSavePhoto(Image<Rgba32> img, string path, int squareSize)
{
    img.Mutate(x =>
        x.Resize(new ResizeOptions
        {
            Size = new Size(squareSize, squareSize),
            Mode = ResizeMode.Pad
        }).BackgroundColor(new Rgba32(255, 255, 255, 0)));

    // The following demonstrates how to force png encoding with a path.
    img.Save(Path.ChangeExtension(path, ".jpg"))

    img.Save(path, new PngEncoder());
}

Additionally, if saving to a stream.

img.SaveAsPng(path);
James South
  • 10,147
  • 4
  • 59
  • 115
0

I had similar symptoms to the OP. The image was getting saved as 24bpp png (no alpha channel), and the parts of the image that were supposed to be transparent after the resize were black.

In my case CloneAs<Rgba32>() seemed to do the trick, converting the clone of the original image from 24 bit to 32 bit.

using (SixLabors.ImageSharp.Image originalImage = await SixLabors.ImageSharp.Image.LoadAsync(imageStream))
{
    SixLabors.ImageSharp.Formats.Png.PngEncoder pngEncoder = new SixLabors.ImageSharp.Formats.Png.PngEncoder() { ColorType = SixLabors.ImageSharp.Formats.Png.PngColorType.RgbWithAlpha };
    
    using (SixLabors.ImageSharp.Image image = originalImage.CloneAs<SixLabors.ImageSharp.PixelFormats.Rgba32>())
    {
        image.Mutate(x => x.Resize(new ResizeOptions() { Size = new Size(100, 100), PadColor = Color.Transparent, Mode = ResizeMode.Pad }));

        using (Stream stream = ....)
        {
            await image.SaveAsPngAsync(stream, pngEncoder);
        }
    }
}

Or instead of CloneAs<Rgba32>(), you can use LoadAsnc<Rgba32>(), whichever makes more sense for your scenario. Just make sure your resize operation is working on a 32 bit image, and not 24 bit.

SixLabors.ImageSharp.Image.LoadAsync<SixLabors.ImageSharp.PixelFormats.Rgba32>(imageStream)

it may not help the OP, but maybe it will be useful to the next Googler that comes along.

CodeMonkey
  • 629
  • 7
  • 16