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

Transparency lost converting eps to png via Magick.NET when ImageMagick source works perfectly

Feb 4, 2014 at 7:14 PM
Edited Feb 4, 2014 at 7:15 PM
I'm having trouble maintaining transparency through Magick.NET converting from an EPS to PNG. When using Magick.NET I'm getting a plain white image, when using ImageMagick console I'm getting exactly what I expect.

A) What am I doing wrong that is causing the transparency loss
B) Is there a way to only pass direct console parameters such as I pass to ImageMagick console app?
C) Is there a way to see what would be passed to the console application upon the conversion?

File in question: http://www.myargosydirect.com/static/dam/assets/000/003/93eaeccc-fcd8-4ef1-bb46-08279a5c881a.eps

ImageMagick Console Code that works:
convert -colorspace RGB -density 72 -verbose 93eaeccc-fcd8-4ef1-bb46-08279a5c881a.eps 93eaeccc-fcd8-4ef1-bb46-08279a5c881a.png
Conversion Code (GetImageFormat returns MagickFormat.Png for this file):
        private void ConvertImage(IEnumerable<ImageSize> sizes, ImageInfo sourceInfo, MagickImage image) {
            foreach (var size in sizes) {
                if (!size.MatteImage) {
                    size.CalculateSize(sourceInfo);
                }
                image.Format = this.GetImageFormat(size.Destination);
                image.ColorSpace = global::ImageMagick.ColorSpace.RGB;
                image.Density = new MagickGeometry(size.Dpi, size.Dpi);
                image.Resize(size.MaxWidth, size.MaxHeight);
                using (var stream = new MemoryStream()) {
                    image.Write(stream);
                    size.Destination.Save(stream.ToArray());
                }
            }
        }
Coordinator
Feb 4, 2014 at 8:06 PM
Edited Feb 4, 2014 at 8:27 PM
A)

You should set the colorspace and density before your read the file to get the correct result. You are also doing that on the command line. You can do this with the MagickReadSettings class. Below is an example.
MagickReadSettings settings = new MagickReadSettings();
settings.ColorSpace = ColorSpace.RGB;
settings.Density = new MagickGeometry(72, 72);

using (MagickImage image = new MagickImage("93eaeccc-fcd8-4ef1-bb46-08279a5c881a.eps", settings))
{
  image.Format = MagickFormat.Png;
  byte[] bytes = image.ToByteArray(); // No need to write to a stream first.
  using (FileStream fs = File.OpenWrite("93eaeccc-fcd8-4ef1-bb46-08279a5c881a.png"))
  {
    fs.Write(bytes, 0, bytes.Length);
  }
}
B) and C)

Magick.NET does not use the console version of ImageMagick it calls the methods that will be called by convert.exe directly. The methods that are used by convert.exe are compiled into the Magick.NET library. Most methods and properties have the same name as their command line equivalent to make it easier to change a command line command into C# code.
Feb 4, 2014 at 8:22 PM
Thanks for the byte array trick, definitely saves some operations and wasted memory!

I'm still having trouble though, I've tried modifying my code to use either of these two blocks and neither generate the correct dpi or maintain transparency for that image. I also tried the Height/Width settings in the MagickReadSettings instead of image.Resize(x,y) but the image maintained the original size. This issues seems to be specific to all ghostscript files, I'm having the same issue with transparency in .ai, .psd and eps files.

Right now I'm trying to convert that eps to a png with 72 dpi (currently 300dpi) and a max resolution of 400x400 while maintaining aspect ratio.
public void ResizeImage(IFileInfo sourceFile, IEnumerable<ImageSize> sizes) {
            if (this.IsValidFormat(sourceFile)) {
                var resizes = sizes as ImageSize[] ?? sizes.ToArray();
                if (sizes == null || !resizes.Any()) {
                    return;
                }
                sizes = resizes.Max(s => s.MaxHeight) > resizes.Max(s => s.MaxWidth) ? resizes.OrderByDescending(s => s.MaxHeight) : resizes.OrderByDescending(s => s.MaxWidth);
                foreach (var size in sizes) {
                    if (!size.MatteImage) {
                        size.CalculateSize(this.GetImageInformation(sourceFile)[0]);
                    }
                    var settings = new MagickReadSettings {
                                                              ColorSpace = global::ImageMagick.ColorSpace.RGB,
                                                              Density = new MagickGeometry(size.Dpi, size.Dpi)
                                                          };
                    using (var image = new MagickImage(sourceFile.Get())) {
                        image.Format = this.GetImageFormat(size.Destination);
                        image.Resize(size.MaxWidth, size.MaxHeight);
                        size.Destination.Save(image.ToByteArray());
                    }
                }
            }
        }
and
public void ResizeImage(IFileInfo sourceFile, IEnumerable<ImageSize> sizes) {
            if (this.IsValidFormat(sourceFile)) {
                var resizes = sizes as ImageSize[] ?? sizes.ToArray();
                if (sizes == null || !resizes.Any()) {
                    return;
                }
                sizes = resizes.Max(s => s.MaxHeight) > resizes.Max(s => s.MaxWidth) ? resizes.OrderByDescending(s => s.MaxHeight) : resizes.OrderByDescending(s => s.MaxWidth);
                foreach (var size in sizes) {
                    if (!size.MatteImage) {
                        size.CalculateSize(this.GetImageInformation(sourceFile)[0]);
                    }
                    var settings = new MagickReadSettings {
                                                              ColorSpace = global::ImageMagick.ColorSpace.RGB,
                                                              Density = new MagickGeometry(size.Dpi, size.Dpi)
                                                          };
                    using (var image = new MagickImage(sourceFile.Get(), settings)) {
                        image.Format = this.GetImageFormat(size.Destination);
                        image.Resize(size.MaxWidth, size.MaxHeight);
                        size.Destination.Save(image.ToByteArray());
                    }
                }
            }
        }
Coordinator
Feb 4, 2014 at 8:35 PM
Edited Feb 4, 2014 at 8:57 PM
I updated the example above. I forgot to add the settings to the constructor. The result is a png with a transparent background and it even reports 72 dpi with the identify command of ImageMagick. Are you using the latest version of Magick.NET?
Feb 4, 2014 at 8:40 PM
According to nuget I'm using 6.8.8.201. Let me run a complete clean build and see if that fixes it.

I'm wondering if I need to generate the image first at the original size with the altered ColorSpace and DPI then perform the resize as a seperate operation.

I'll report back in a few minutes.
Feb 4, 2014 at 9:25 PM
Looks like that is the issue, I need to generate the file as a png without resizing first. Then resize the png to what I want.

On a side note I have been able to reproduce a bug with ai files that contain spot color gradients (that's what the graphics guy referred to them as). Here is an example if you'd like to dig into it, but basically when you pass the attached ai file to new MagickImage(ai-file) it just hangs permanently.

File in question: www.myargosydirect.com/static/dam/assets/000/003/37cf370d-6523-45ae-9839-858c592d5460.ai

Thanks for all your assistance!

Andrew
Coordinator
Feb 4, 2014 at 9:37 PM
Edited Feb 19, 2014 at 10:51 AM
I can reproduce the problem with your ai image but I am unable to fix it. The problem seems to be in the Ghostscript library. You should report the bug here: http://bugs.ghostscript.com.
Feb 4, 2014 at 9:56 PM
I've log a bug in their system http://bugs.ghostscript.com/show_bug.cgi?id=695012. If there is anymore specific information you could provide them that would be great.

Thanks!
Andrew
Coordinator
Feb 7, 2014 at 11:10 PM
Edited Feb 8, 2014 at 12:19 AM
It looks like the bug with your ai file will be fixed in Ghostscript 9.11.