This project has moved. For the latest updates, please go here.

Converting from AI/SVG to PNG with transparent backgrounds.

Mar 4, 2016 at 5:06 PM
Hey,
So I am having an issue with converting my images to png while maintaining transparency.
My code currently looks like this:
public async Task<string> ConvertImage(byte[] data)
{

    // Reader settings
    var settings = new MagickReadSettings
    {
        Density = new PointD(300, 300),
        ColorSpace = ColorSpace.RGB,
        Format = MagickFormat.Svg
    };

    // Create our image
    using (var image = new MagickImage(data, settings))
    {

        // Create a new memory stream
        using (var memoryStream = new MemoryStream())
        {

            // Set our image properties
            image.Format = MagickFormat.Png;
            image.Resize(600, 600);      

            // Write to our stream
            image.Write(memoryStream);

            // Reset our memory stream position
            memoryStream.Position = 0;

            // Create a new blob block to hold our image
            var blockBlob = container.GetBlockBlobReference(Guid.NewGuid().ToString() + ".png");

            // Upload to azure
            await blockBlob.UploadFromStreamAsync(memoryStream);

            // Return the blobs url
            return blockBlob.StorageUri.PrimaryUri.ToString();
        }
    }
}
The image is created successfully, but it is never transparent. I did try doing this:
 image.TransparentChroma(new MagickColor("white"), new MagickColor("white"));
and that sort of works (except there is a clear white outline to the image). This is not a valid solution though, because some of my images are actually white on a transparent background.
Does anyone know how I can convert and retain the transparency?

I am using Magick.Net-Q16-AnyCPU.
Mar 4, 2016 at 5:21 PM
Edited Mar 4, 2016 at 5:22 PM
I have also tried the suggestion in this post: https://magick.codeplex.com/discussions/646230 but it doesn't work for me. It just generates an unreadable file. The code I changed now looks like this:
// Create our image
using (var image = new MagickImage())
{

    // Set our image properties
    image.BackgroundColor = new MagickColor(0, 0, 0, 0);

    // Read our image
    image.Read(data);

    // Create a new memory stream
    using (var memoryStream = new MemoryStream())
    {

        // Change the format and resize
        image.Format = MagickFormat.Png24;
        //image.Resize(600, 600);

        // Write to our stream
        image.Write(memoryStream);

        // Reset our memory stream position
        memoryStream.Position = 0;

        // Create a new blob block to hold our image
        var blockBlob = container.GetBlockBlobReference(Guid.NewGuid().ToString() + ".png");

        // Upload to azure
        await blockBlob.UploadFromStreamAsync(memoryStream);

        // Return the blobs url
        return blockBlob.StorageUri.PrimaryUri.ToString();
    }
}
and the SVG I am trying to convert looks like this:
    <?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="kudos_logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 421.4 378.8" enable-background="new 0 0 421.4 378.8" xml:space="preserve">
<g id="kudos-logo-ident-front">
    <path d="M15.5,82.2L86,82.3l0.7,0.8l-0.1,78.7c8.7-12.7,17.3-25.4,26-38.1c6.1-9,12.2-17.9,18.4-27c2.5-3.7,9.6-15.1,9.6-15.1
        c10.7-22.8,230.7,21.1,264.2-67.4c0.7-1.4,1.6-2.3,1.5-1.2c-11.9,90.6-202.7,81.6-205.9,86.7c-10.2,17.4-18.2,27.5-24.8,37.2
        c-7.5,11.1-15.1,22.2-22.2,33.6v0.4l65.7,100.3l-0.5,0.4l-74.1-0.2c-1.3-0.9-10.9-15.3-28.7-43.3c-18.5-27.6-28.1-42.3-28.8-44.2
        l-0.4-0.1l-0.2,86.6l-0.8,0.8L15,271.3l-0.9-0.8l0.6-187.6L15.5,82.2z"/>
    <path d="M184.5,154.7c8.6-12.6,32.3-31.5,48.5-38.2c12-4.9,23.2-9.1,36.1-10.2c17.8-1.4,92.8,16.6,138.2-45
        c-0.6,22.1-29.6,48.8-41.5,56.4c-19,12.1-33.8,18.5-55.5,17.3c-24.1-1.4-66.9-15.6-125.3,19.3"/>
    <path d="M170.4,174.5c10.5-9.5,35-24.1,49.6-25.7c10.9-1.1,21-1.8,31.4,0.9c14.1,3.7,70.4,42.2,125.2-2.9
        c-7.4,23.1-42.2,41.5-53.8,45.1c-18.8,5.9-32.2,7.6-48.6,0.2c-18.2-8.1-46.9-34-103.3-17.8"/>
    <path d="M169.3,184.2c9.9-2.9,32.5-4.3,43.1-2.6c16.4,2.3,19,7.8,23.8,13.8c7.9,9.6,27.1,47.3,77.2,34.4
        c-12.1,13-40.7,14.3-49.5,13.1c-14.2-1.8-23.5-4.7-32-14.8c-9.5-11.1-20.2-37-62.3-43.8"/>
    <path d="M229.4,255.9h2.6c1.3,0,2.2-0.2,2.8-0.5c0.6-0.3,0.8-0.9,0.8-1.7c0-0.7-0.3-1.2-0.8-1.6c-0.5-0.3-1.4-0.5-2.5-0.5h-2.9
        V255.9z M226.3,264.8V249h7.5c1.9,0,3.2,0.4,4,1.3c0.8,0.9,1.3,1.9,1.3,3.2c0,1.2-0.4,2.2-1.1,2.9c-0.7,0.7-1.8,1.2-3.2,1.5
        c0.6,0.3,1.1,0.6,1.5,1c0.4,0.4,1,1.3,1.8,2.7l1.8,3.2H236l-1.3-2.5c-0.8-1.5-1.5-2.5-2.1-3.1c-0.6-0.5-1.4-0.8-2.4-0.8h-0.8v6.5
        H226.3z M233.2,244.9c-3.6,0-6.6,1.2-8.9,3.6c-2.3,2.4-3.4,5.2-3.4,8.4c0,3.3,1.2,6.1,3.5,8.4c2.3,2.3,5.2,3.5,8.4,3.5
        c3.3,0,6.1-1.2,8.4-3.5c2.3-2.3,3.5-5.2,3.5-8.4c0-2.3-0.6-4.3-1.8-6.3c-1.2-1.9-2.7-3.3-4.5-4.3
        C236.6,245.4,234.8,244.9,233.2,244.9 M232.4,242c4.4,0,8.1,1.5,11,4.4c2.9,2.9,4.3,6.4,4.3,10.4c0,4.1-1.4,7.6-4.4,10.5
        c-2.9,2.9-6.4,4.4-10.5,4.4c-4.1,0-7.6-1.4-10.5-4.3c-2.9-2.9-4.3-6.4-4.3-10.5c0-2.9,0.8-5.5,2.3-8c1.5-2.4,3.4-4.2,5.8-5.3
        C228.3,242.6,230.4,242,232.4,242"/>
</g>
<g id="kudos-logo-text">
    <path d="M14.4,300.1H39l0.3,0.3v27.5l18.8-27.7h24.6l0.3,0.3c-11.3,16.6-18.1,26.7-20.4,30.5v0.1l23,34.9l-0.1,0.1H59.6
        c-0.5-0.3-3.8-5.3-10.1-15.1c-6.4-9.6-9.8-14.7-10.1-15.4h-0.1v30.2l-0.3,0.3H14.4l-0.3-0.3v-65.4L14.4,300.1z"/>
    <path d="M91.4,300h25.1l0.3,0.3V344c0,3.1,1.1,5.2,3.2,6h15.2c2.2,0,3.4-2,3.7-5.9v-43.8l0.3-0.3h25l0.3,0.3v49.3
        c0,5.1-3,9.6-8.9,13.5c-3.3,2-7.4,3-12.4,3h-30.8c-9.9,0-16.8-4.1-20.6-12.4c-0.6-2-0.9-4-0.9-6v-47.4L91.4,300z"/>
    <path d="M172.4,300h54.2c5.1,0,10,2.3,14.7,6.9c2.6,3.4,3.9,6.5,3.9,9.2v33.5c0,5.1-3,9.6-8.9,13.5c-3.3,2-7.5,3-12.4,3h-51.4
        l-0.3-0.3v-65.5L172.4,300z M197.4,314.2V350h18.4c2.2,0,3.4-2,3.7-6v-23.4c0-3.7-1.2-5.8-3.6-6.3H197.4z"/>
    <path d="M271.7,300h35.6c5.5,0,10.6,2.4,15.1,7.2c2.5,3.2,3.7,6.2,3.7,8.9v33.5c0,5.1-3,9.6-8.9,13.5c-3.3,2-7.4,3-12.4,3h-30.8
        c-9.9,0-16.8-4.1-20.6-12.4c-0.6-2-0.9-4-0.9-6v-29.5c0-8.5,4.7-14.4,14.2-17.5C268.7,300.2,270.3,300,271.7,300z M278.5,320.5
        v23.1c0,3.4,1.1,5.5,3.2,6.3h15.2c2.2,0,3.4-2,3.7-5.9v-23.6c0-4.2-1.4-6.3-4.2-6.3h-13.8C279.8,314.2,278.5,316.3,278.5,320.5z"/>
    <path d="M352.8,300h33.6c5.9,0,11.2,2.7,15.8,8c2.1,2.8,3.2,6.4,3.2,10.8v2.3l-0.3,0.3h-25.2l-0.3-0.3c0-3.4-0.7-5.4-2-6
        c-0.8-0.6-2-0.9-3.7-0.9h-8.2c-4.2,0-6.3,1.4-6.3,4.2v0.1c0,1.8,0.9,3,2.7,3.7c19.2,3,30.7,5.1,34.5,6.3
        c7.1,2.4,10.6,6.7,10.6,12.8v8.2c0,5.1-3,9.6-8.9,13.5c-3.3,2-7.5,3-12.4,3h-30.8c-9.9,0-16.8-4.1-20.5-12.4c-0.6-2-0.9-4-0.9-6v-5
        l0.3-0.3h25.2l0.3,0.3v1.1c0,4.1,2.2,6.2,6.8,6.2h9.8c2.9,0,4.9-1.1,5.7-3.3v-1.4c0-2-1.7-3.4-5-4.3c-17.9-2.7-29-4.7-33.2-6.2
        c-4.9-2-7.9-4.6-9.1-7.6c-0.5-1.3-0.7-2.9-0.7-4.7v-4.2c0-8.5,4.7-14.3,14.1-17.5C349.8,300.2,351.5,300,352.8,300z"/>
</g>
</svg>
Coordinator
Mar 5, 2016 at 9:18 PM
You should set image.Settings.BackgroundColor instead of image.BackgroundColor.
Mar 7, 2016 at 9:33 AM
Hi, that didn't work. Just makes the entire image transparent.
Mar 7, 2016 at 11:55 AM
Ok, so I have been playing around with this and here are a few things I have noticed.

If I used:
image.Settings.BackgroundColor = new MagickColor(System.Drawing.Color.Red);
then the background is infact red and I can actually see the rest of my image (i.e. the logo)

if I try:
image.Settings.BackgroundColor = MagickColors.Transparent;
then everything is transparent and I can't see anything. I have checked the dimensions of the image and they are 500px wide and about the same height so it isn't that it's too small to see.
So, I thought I would do a combination of the 2 to see what happens.
So I tried:
image.Settings.BackgroundColor = new MagickColor("#7FFF0000"); // Red at 50% transparency
I would expect to see a transparent red background at 50% transparency, but instead I still get an entirely transparent image :(

All this has been happening with this SVG file: http://portalvhdswfr5fqfcn6r95.blob.core.windows.net/kudos-sports/67c49467-c9ed-4662-a4a6-08ed2c3536ce.svg
If I try with the AI file I just get a white background :(
Surely this has happened to others?
Coordinator
Mar 7, 2016 at 4:48 PM
Edited Mar 7, 2016 at 4:54 PM
I am suspecting that you are using the image viewer on Windows 10 to view your image. This shows transparent as black and because your text is black it will look like a black/transparent image. When you drag the file into a browser you will see the black logo.

And your color specification is incorrect. When you read the help text of the constructor it will tell you that it expects RGBA. So it should be #FF00007F instead of #7FFF0000"
Mar 9, 2016 at 9:09 AM
Hi,

No I am viewing my image in the browser.

I chanced the RGBA to #FF00007F and something weird happened. The black is now transparent and the transparent bit is now red.

Image
Mar 9, 2016 at 9:12 AM
Edited Mar 9, 2016 at 12:26 PM
While I am linking my images, here is one when I use the code like this:
/// <summary>
/// Converts any image to png and uploads it to azure
/// </summary>
/// <param name="data">The byte array of the image</param>
/// <returns>The path to the azure blob</returns>
public async Task<string> ConvertImage(byte[] data, bool replaceBlack)
{

    // Create our image
    using (var image = new MagickImage())
    {
        image.Settings.BackgroundColor = MagickColors.Transparent;

        // Read our image
        image.Read(data);

        // Create a new memory stream
        using (var memoryStream = new MemoryStream())
        {

            // Set to a png
            image.Format = MagickFormat.Png24;
            image.Resize(600, 600);

            // Write to our stream
            image.Write(memoryStream);

            // Reset the memory stream position
            memoryStream.Position = 0;

            // Create a new blob block to hold our image
            var blockBlob = container.GetBlockBlobReference(Guid.NewGuid().ToString() + ".png");

            // Upload to azure
            await blockBlob.UploadFromStreamAsync(memoryStream);

            // Return the blobs url
            return blockBlob.StorageUri.PrimaryUri.ToString();
        }
    }
}
This is the image that is produced:

Image
Mar 11, 2016 at 9:13 AM
any ideas?
Coordinator
Mar 11, 2016 at 10:57 AM
Edited Mar 11, 2016 at 10:59 AM
It appears that you need to set the background color of the image when you write it. I missed that you were writing a PNG24 file instead of a PNG32 one. PNG24 only supports background transparency. The default background color is Transparent. When you change your code to my example below you will get the result that you want.
byte[] data = File.ReadAllBytes("67c49467-c9ed-4662-a4a6-08ed2c3536ce.svg");
using (var image = new MagickImage())
{
  MagickReadSettings settings = new MagickReadSettings()
  {
    Width = 600,
    Height = 600
  };

  image.Settings.BackgroundColor = new MagickColor("#FF00007F");
  image.Read(data, settings);

  image.BackgroundColor = new MagickColor("#FF00007F");
  image.Format = MagickFormat.Png24;
  image.Write("output.png");
}
I would advise you to specify the maximum size of your image when you read it instead of doing a resize. I am doing that in the example above.

I am going to change the behaviour in the next release of Magick.NET. Setting the MagickImage BackgroundColor will also set the Settings.BackgroundColor to make this more convenient. You can change your code to this then:
  image.BackgroundColor = new MagickColor("#FF00007F");
  image.Read(data, settings);

  image.Format = MagickFormat.Png24;
  image.Write("output.png");
Mar 11, 2016 at 3:12 PM
Hey,

Thanks for this, it works.

I didn't realise that png24 only supports background transparency.
If I change to png32, does the code need to be the same?
Coordinator
Mar 12, 2016 at 6:21 AM
Edited Mar 12, 2016 at 6:22 AM
Changing the format from png24 to png32 should resolve your issue. Then you can leave the rest of the code the same. But please look at my remark about reading the image with the MagickReadSettings instead of resizing it.