File comes up black in ImageMagick but shows fine in ImageJ does anyone know why? It is 16 bit grayscale

Viewed 28

enter image description here

enter image description hereenter image description here

When I attempt to open this image in GIMP it also comes up as black, same as in ImageSharp,enter image description here

enter image description here

just confused about how to show this tif, ImageSharp doesn't even recognize it as 16 bit grayscale so i'm trying to find a way to display this image using C#, i'd like to use MagickImage if Could. It's coming from a microscope.

any help would be greatly appreciated

the image doesn't allow itself to be shared on stack overflow it just says the link is brokenenter image description here

//here are the parameters imagemagick gives me:
Name: AnimationDelay, Value: 0
Name: AnimationIterations, Value: 0
Name: AnimationTicksPerSecond, Value: 100
Name: ArtifactNames, Value: ImageMagick.MagickImage+<get_ArtifactNames>d__43
Name: AttributeNames, Value: ImageMagick.MagickImage+<get_AttributeNames>d__45
Name: BackgroundColor, Value: #FFFFFFFFFFFFFFFF
Name: BaseHeight, Value: 2040
Name: BaseWidth, Value: 2040
Name: BlackPointCompensation, Value: False
Name: BorderColor, Value: #DFDFDFDFDFDFFFFF
Name: BoundingBox, Value: 
Name: ChannelCount, Value: 1
Name: Channels, Value: ImageMagick.MagickImage+<get_Channels>d__64
Name: ChromaBluePrimary, Value: ImageMagick.PrimaryInfo
Name: ChromaGreenPrimary, Value: ImageMagick.PrimaryInfo
Name: ChromaRedPrimary, Value: ImageMagick.PrimaryInfo
Name: ChromaWhitePoint, Value: ImageMagick.PrimaryInfo
Name: ClassType, Value: Direct
Name: ColorFuzz, Value: 0%
Name: ColormapSize, Value: -1
Name: ColorSpace, Value: Gray
Name: ColorType, Value: Grayscale
Name: Comment, Value: 
Name: Compose, Value: Over
Name: Compression, Value: LZW
Name: Density, Value: 0x0 inch
Name: Depth, Value: 16
Name: EncodingGeometry, Value: 
Name: Endian, Value: LSB
Name: FileName, Value: C:\\Users\\jdmso\\Downloads\\mystery.tif
Name: FilterType, Value: Undefined
Name: Format, Value: Tiff
Name: FormatInfo, Value: Tiff: Tagged Image File Format (+R+W+M)
Name: Gamma, Value: 0.45454545454545453
Name: GifDisposeMethod, Value: Undefined
Name: HasAlpha, Value: False
Name: Height, Value: 2040
Name: Interlace, Value: NoInterlace
Name: Interpolate, Value: Undefined
Name: IsDisposed, Value: False
Name: IsOpaque, Value: True
Name: Label, Value: 
Name: MatteColor, Value: #BDBDBDBDBDBDFFFF
Name: Orientation, Value: TopLeft
Name: Page, Value: 2040x2040
Name: ProfileNames, Value: ImageMagick.MagickImage+<get_ProfileNames>d__154
Name: Quality, Value: 0
Name: RenderingIntent, Value: Undefined
Name: Settings, Value: ImageMagick.MagickReadSettings
Name: Signature, Value: 5639160dfdd3d30c160b4dcb3edf252d9c24266393e60ae8500c5457f7ee23b5
Name: TotalColors, Value: 1
Name: VirtualPixelMethod, Value: Undefined
Name: Width, Value: 2040

I don't know how to share the zip file?

1 Answers

For 16 bit grayscale, we may use auto-level option:

image.AutoLevel();

Assume your PC supports only 8 bits grayscale display (in RGB format, the grayscale is displayed as 8 bits per red, green and blue, when r=g=b for each pixel).

When we want to display a 16 bits image, we have to convert it to 8 bits first.
The default conversion used by your viewer is getting the upper 8 bits of every 16 bits, and ignoring the lower 8 bits (equivalent of dividing all pixels by 256).

In case the pixels range is about [0, 255] for example (or say [0, 1000]), the image is going to be very dark, or entirely black.
In your case, the pixels range is probably low, so the displayed image looks black.

The "auto-level" processing, adjusts the pixel range using "linear stretching".
Finds the minimum and the maximum pixel values, and applies scale and offset that brings the minimum to 0 (black) and the maximum to 255 [or 65535 for 16bits] (white).


For correctly handling 16 bit images, we have to install Magick.NET-Q16.
See the following post for details.

For testing, I used the oldest release of MagickViewer.

Added the following code:

//Update for automatic ajusting the 16 bits image for display
////////////////////////////////////////////////////////////////////////////
foreach (var image in Images)
{
    image.AutoLevel();
}
////////////////////////////////////////////////////////////////////////////

Complete testing code:

//=================================================================================================
// Copyright 2013-2014 Dirk Lemstra <https://magickviewer.codeplex.com/>
//
// Licensed under the ImageMagick License (the "License"); you may not use this file except in 
// compliance with the License. You may obtain a copy of the License at
//
//   http://www.imagemagick.org/script/license.php
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing permissions and
// limitations under the License.
//=================================================================================================
//https://github.com/dlemstra/MagickViewer/tree/6.8.9.501

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Threading;
using ImageMagick;
using Microsoft.Win32;

namespace MagickViewer
{
    //==============================================================================================
    internal sealed class ImageManager
    {
        //===========================================================================================
        private static readonly object _Semaphore = new object();
        private static readonly string[] _GhostscriptFormats = new string[]
        {
            ".EPS", ".PDF", ".PS"
        };
        //===========================================================================================
        private Dispatcher _Dispatcher;
        private OpenFileDialog _OpenDialog;
        private SaveFileDialog _SaveDialog;
        //===========================================================================================
        private void ConstructImages()
        {
            if (Images != null)
                Images.Dispose();

            Images = new MagickImageCollection();
        }
        //===========================================================================================
        [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase")]
        private static string CreateFilter(IEnumerable<MagickFormatInfo> formats)
        {
            string filter = "All supported formats (...)|*." + string.Join(";*.",
                                            from formatInfo in formats
                                            orderby formatInfo.Format
                                            select formatInfo.Format.ToString().ToLowerInvariant());

            filter += "|" + string.Join("|",
                                            from formatInfo in formats
                                            orderby formatInfo.Description
                                            group formatInfo.Format by formatInfo.Description into g
                                            select g.Key + "|*." + string.Join(";*.", g).ToLowerInvariant());
            return filter;
        }
        //===========================================================================================
        private void Initialize()
        {
            _OpenDialog = new OpenFileDialog();
            SetOpenFilter();

            _SaveDialog = new SaveFileDialog();
            SetSaveFilter();
        }
        //===========================================================================================
        private void OnLoaded()
        {
            if (Loaded == null)
                return;

            _Dispatcher.Invoke((Action)delegate()
            {
                Loaded(this, EventArgs.Empty);
                Monitor.Exit(_Semaphore);
            });
        }
        //===========================================================================================
        private void OnLoading()
        {
            if (Loading != null)
                Loading(this, EventArgs.Empty);
        }
        //===========================================================================================
        private void ReadImage(FileInfo file)
        {
            ConstructImages();

            try
            {
                MagickReadSettings settings = new MagickReadSettings();
                if (_GhostscriptFormats.Contains(file.Extension.ToUpperInvariant()))
                    settings.Density = new MagickGeometry(300, 300);

                Images.Read(file, settings);
                FileName = file.Name;

                //Update for automatic ajusting the 16 bits image for display
                ////////////////////////////////////////////////////////////////////////////
                foreach (var image in Images)
                {
                    image.AutoLevel();
                }
                ////////////////////////////////////////////////////////////////////////////
            }
            catch (MagickErrorException)
            {
                //TODO: Handle error
            }

            OnLoaded();
        }
        //===========================================================================================
        private void Save(string fileName)
        {
            Images.Write(fileName);
        }
        //===========================================================================================
        private void SetOpenFilter()
        {
            var formats = from formatInfo in MagickNET.SupportedFormats
                              where formatInfo.IsReadable
                              select formatInfo;

            _OpenDialog.Filter = CreateFilter(formats);
        }
        //===========================================================================================
        private void SetSaveFilter()
        {
            var formats = from formatInfo in MagickNET.SupportedFormats
                              where formatInfo.IsWritable
                              select formatInfo;

            _SaveDialog.Filter = CreateFilter(formats);
        }
        //===========================================================================================
        public ImageManager(Dispatcher dispatcher)
        {
            _Dispatcher = dispatcher;

            Initialize();
        }
        //===========================================================================================
        public event EventHandler Loading;
        //===========================================================================================
        public event EventHandler Loaded;
        //===========================================================================================
        public string FileName
        {
            get;
            private set;
        }
        //===========================================================================================
        public MagickImageCollection Images
        {
            get;
            private set;
        }
        //===========================================================================================
        public static bool IsSupported(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
                return false;

            if (fileName.Length < 2)
                return false;

            string extension = Path.GetExtension(fileName);
            if (string.IsNullOrEmpty(extension))
                return false;

            extension = extension.Substring(1);
            MagickFormat format;
            if (!Enum.TryParse<MagickFormat>(extension, true, out format))
                return false;

            return (from formatInfo in MagickNET.SupportedFormats
                      where formatInfo.IsReadable && formatInfo.Format == format
                      select formatInfo).Any();

        }
        //===========================================================================================
        public void Load(string fileName)
        {
            Monitor.Enter(_Semaphore);

            OnLoading();

            Thread thread = new Thread(() => ReadImage(new FileInfo(fileName)));
            thread.Start();
        }
        //===========================================================================================
        public void ShowOpenDialog()
        {
            if (_OpenDialog.ShowDialog() != true)
                return;

            Load(_OpenDialog.FileName);
        }
        //===========================================================================================
        public void ShowSaveDialog()
        {
            if (_SaveDialog.ShowDialog() != true)
                return;

            Save(_SaveDialog.FileName);
        }
        //===========================================================================================
    }
    //==============================================================================================
}
Related