Converting SVG to PNG with premultiplied alpha channel

Magick.NET is an object-oriented C# interface to ImageMagick. Use this forum to discuss, make suggestions about, or report bugs concerning Magick.NET
Post Reply
tarasm
Posts: 4
Joined: 2019-10-22T08:15:35-07:00
Authentication code: 1152

Converting SVG to PNG with premultiplied alpha channel

Post by tarasm »

Hi all,
I am trying to create a png from svg, but i need the alpha channel, premultiplied to black.
My code below creates a png with a "pure" transparency.

Code: Select all

                MagickReadSettings readSettings = new MagickReadSettings()
                {
                    Format = MagickFormat.Svg,
                    TextAntiAlias = true,
                    StrokeAntiAlias = true,
                    ColorSpace = ColorSpace.Transparent,
                    BackgroundColor = MagickColors.Black
                };
                readSettings.BackgroundColor = MagickColors.Transparent;

                byte[] SvgBytes = Encoding.UTF8.GetBytes(svgDoc.OuterXml);
                using (MagickImage image = new MagickImage(SvgBytes, readSettings))
                {
                    image.Format = MagickFormat.Png;
                    image.Alpha(AlphaOption.Set);
                    image.Write(filename);
                }
How can i achieve the premultiplied alpha?

snibgo
Posts: 12863
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Converting SVG to PNG with premultiplied alpha channel

Post by snibgo »

tarasm wrote:i need the alpha channel, premultiplied to black.
What does "premultiplied to black" mean? Normally, pre-multiplying by alpha means that colour values are multiplied by alpha before some operation, and divided by alpha after the operation. But you seem to mean something different.
snibgo's IM pages: im.snibgo.com

tarasm
Posts: 4
Joined: 2019-10-22T08:15:35-07:00
Authentication code: 1152

Re: Converting SVG to PNG with premultiplied alpha channel

Post by tarasm »

I mean that original colors become darker there where transparency is present, proportional to transparency, but keeping the alpha channel itself intact.
An effect similar, if i would put my image with transparency on a black background, store the resulting values of the semi-transparent pixels in my image, remove the black background and then write my image with new colors and the original alpha channel.
Is it too confusing?

snibgo
Posts: 12863
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Converting SVG to PNG with premultiplied alpha channel

Post by snibgo »

Perhaps you want to save the alpha channel, then flatten the image over a black background, then restore the original alpha values. At the command line:

Code: Select all

magick in.png ^
  ( -alpha extract mpr:SAVED +delete ) ^
  -background Black -layers Flatten ^
  mpr:SAVED -alpha off -compose CopyOpacity -composite ^
  out.png
Doubtless that can be done in Magick.NET, but I don't know how, sorry.
snibgo's IM pages: im.snibgo.com

User avatar
fmw42
Posts: 26249
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Converting SVG to PNG with premultiplied alpha channel

Post by fmw42 »

I was thinking something similar to user snibgo, but doing a multiply. First extract the alpha channel and save it to mpr:. Then multiply it against the image. Then put the saved alpha channel back into the resulting image's alpha channel.

Unix syntax:

Code: Select all

magick img.png \
\( +clone -alpha extract +write mpr:alpha \) \
-compose multiply -composite -compose over \
mpr:alpha -alpha off -compose copy_opacity -composite \
result.png

tarasm
Posts: 4
Joined: 2019-10-22T08:15:35-07:00
Authentication code: 1152

Re: Converting SVG to PNG with premultiplied alpha channel

Post by tarasm »

thank you fmv42 and snibgo, i saw something similar to your solutions using the command line, but i was hoping someone can indicate me how to do this in magick,net

tarasm
Posts: 4
Joined: 2019-10-22T08:15:35-07:00
Authentication code: 1152

Re: Converting SVG to PNG with premultiplied alpha channel

Post by tarasm »

for those having a similar problem, here is my solution:

Code: Select all

                            byte[] SvgBytes = Encoding.UTF8.GetBytes(svgDoc.OuterXml);
                            using (MagickImage image = new MagickImage(SvgBytes, readSettings))
                            {
                                MagickImage alpha = (MagickImage)image.Separate(Channels.Alpha).First();
                                using (MagickImage bg = new MagickImage("xc:black", image.Width, image.Height))
                                {
                                    bg.Composite(image, CompositeOperator.Atop);
                                    bg.Composite(alpha, CompositeOperator.CopyAlpha);

                                    bg.Format = MagickFormat.Png;
                                    bg.Alpha(AlphaOption.Set);

                                    bg.Write(filename);
                                }
                            }
I am sure it can be optimized in many ways though.

Post Reply