Search code examples
c#imagemagickmagick.netbit-depth

How to set bit depth in Magick.NET Read


How can I specify the bit depth for the MagickImage.Read() function when reading binary files?

I have a 1024x1024 image represented by 8-bit grayscale values (total file length = 1024x1024 = 1048576 bytes). Using ImageMagick v.7.0.8-7 Q16 x64, I can convert the file using

magick.exe -depth 8 -size 1024x1024 -format Gray Gray:filepath.bin convertedfile.png

When I try to convert the file using Magick.NET Q16-AnyCPU v7.5.0.1,

public MagickImage ReadNewMagickImageFromBinary(string fileName){
    MagickReadSettings settings = new MagickReadSettings();

    settings.Width = 1024;
    settings.Height = 1024; //if I use settings.Height = 512; , I'm OK.
    settings.Format = MagickFormat.Gray;
    //settings.Depth = 8;                                   //didn't work
    //settings.SetDefine(MagickFormat.Gray, "depth", "8");  //also didn't work

    MagickImage newImage = new MagickImage();
    newImage.Depth = 8; //this appears to be ignored once the Read function is called
    newImage.Read(fileName, settings);

    return newImage;
}

I get the error

Message: ImageMagick.MagickCorruptImageErrorException : unexpected end-of-file '': No such file or directory @ error/gray.c/ReadGRAYImage/241

Indicating that the program has read past the end of the file. I've confirmed that Magick.NET is reverting to a 16-bit depth instead of the 8-bit depth I want. I can read the file using settings.Height = 512 instead of 1024, which gives me a squashed version of my grayscale image.

I learned from Memory consumption in Magick.NET that Magick.NET Q16 stores pixels in memory with 16-bit precision; I'm fine with that but it doesn't seem that should preclude 8-bit reading capabilities.

How do I force Magick.NET Q16 to read pixels in with an 8-bit depth?


Solution

  • I just published Magick.NET 7.6.0.0 that now has better API for reading raw pixels. You should change your code to this:

    public MagickImage ReadNewMagickImageFromBinary(string fileName)
    {
        var width = 1024;
        var height = 1024;
        var storageType = StorageType.Char;
        var mapping = "R";
        var pixelStorageSettings = new PixelStorageSettings(width, height, storageType, mapping);
    
        return new MagickImage(fileName, pixelStorageSettings);
    }