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

Error Reading Pages as PNGs with Byte Arrays

May 26, 2015 at 4:34 PM
Hello again,

I'm trying to initialize an image collection with the .Read overload using a byte array and settings object. The Format property is set to MagickFormat.Png. This works fine when I use the FileInfo overload. However, if I try to read the file and pass in the byte array, it throws the following:

ImproperImageHeader @ error/png.c/ReadPNGImage/3973 magick.net

Here's my method:
internal static IEnumerable<string> GetDocumentImagesAsBase64(byte[] documentBytes)
{
    MagickReadSettings magickSettings;
    InitializeSettings(MagickFormat.Png, out magickSettings);
            
    List<string> strings = new List<string>();
            
    using (var imageCollection = new MagickImageCollection())
    {
        imageCollection.Read(documentBytes, magickSettings);

        if (imageCollection.Count <= 0) return null;

        strings.AddRange(imageCollection.Select(magickImage => magickImage.ToBase64()));
    }

    return strings;
}

private static void InitializeSettings(MagickFormat format, out MagickReadSettings magickSettings)
{
    const double imageOutputDpi = (double)150;

    magickSettings = new MagickReadSettings
    {
        Density = new PointD(imageOutputDpi, imageOutputDpi),
        Format = format,
        ColorSpace = ColorSpace.GRAY
    };
}
A quick Google lead me here: http://stackoverflow.com/questions/8109536/imagemagick-not-working-with-png-files

This has me curious if the internal ImageMagick libraries have been built with the stated options as noted in that URL, granted it talks about Ruby. Though, why it works with a file reference but not with a byte array is puzzling to me. Is there anything you can suggest?
Coordinator
May 26, 2015 at 10:17 PM
Are you sure that you are providing a correct byte array? I just tried the following and it works without any problem:
using (MagickImage image = new MagickImage("logo:"))
{
  using (MemoryStream stream = new MemoryStream())
  {
    image.Format = MagickFormat.Png;
    image.Write(stream);

    stream.Position = 0;
    using (MagickImage output = new MagickImage(stream.ToArray()))
    {
    }
  }
}
May 27, 2015 at 12:41 PM
It's a byte array that gets initially instantiated via File.ReadAllBytes(string) with the string being the PDF location and stored in a database table via Entity Framework which handles BLOBs as byte arrays. So, is it the correct byte array in terms of is it the entire array of the PDF in question? The answer is yes. Did you mean correct in some other way?
May 27, 2015 at 1:27 PM
The following solution produces the above error for me: https://www.dropbox.com/s/2uwk4kzbwj8zt0k/PDF%20Image%20with%20Byte%20Array.7z?dl=0
Coordinator
May 31, 2015 at 10:03 AM
You got the following MagickReadSettings in your example project:
MagickReadSettings settings = new MagickReadSettings
{
  Density = new PointD(150, 150),
  Format = MagickFormat.Png,
  ColorSpace = ColorSpace.GRAY
};
When you set the Format to MagickFormat.Png you are telling Magick.NET/ImageMagick that the input buffer should be read as a .PNG file. But since your input is PDF it fails to read the file.