I am trying to make a WinForms app in VB.NET (Framework 4.7.2) that optimizes an electronic signature using ImageSharp, and I am running into a problem. When I try to use the OctreeQuantizer to decrease the number of colors in the PNG, I get an inverted / negative image if the source has a transparent background. This is a problem since the signature will need to be transparent when it is applied to a document.
Application Window - Top is original signature
Original Save Dialog from Paint.NET
As you can see, I saved the original image as an 8bpp PNG with transparency using Paint.NET
Here's my quantize function:
Public Shared Function QuantizeImageGrayscalePNG(ByVal vstrSource As String, ByVal vintMaxColors As Integer) As Bitmap
Dim poqQuant As New OctreeQuantizer()
Dim pencPNG As New PngEncoder() With {.BitDepth = PngBitDepth.Bit8, .ColorType = PngColorType.GrayscaleWithAlpha}
vintMaxColors = Math.Min(256, vintMaxColors)
If vstrSource IsNot Nothing AndAlso IO.File.Exists(vstrSource) AndAlso vintMaxColors > 0 Then
Using piNew As Image = Image.Load(vstrSource),
pstOutput As New IO.MemoryStream()
poqQuant.Options.MaxColors = vintMaxColors
piNew.Mutate(Sub(x) x.Quantize(poqQuant))
piNew.Save(pstOutput, pencPNG)
Return Bitmap.FromStream(pstOutput)
End Using
Else
Return Nothing
End If
End Function
If I use an image with no transparency as the source, the issue does not occur. I also tried commenting out the Mutate function, and it "works" but of course does not change the number of colors or image size.
CodePudding user response:
Answer from JimBobSquarePants on GitHub:
Octree only supports a single transparent color . For Png you need to use the Wu quantizer which is the default quantizer.
However, if you are trying to reduce the colors in a png you should be saving it in indexed format by setting the PngColorType in the encoder along with a custom Wu quantizer with your max color count.
Not sure that is a full answer, but my issue was closed so that's all I'm getting.