简体   繁体   English

文件在 ImageMagick 中显示为黑色,但在 ImageJ 中显示正常,有人知道为什么吗? 它是 16 位灰度

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

在此处输入图像描述

enter image description here在此处输入图像描述在此处输入图像描述

When I attempt to open this image in GIMP it also comes up as black, same as in ImageSharp,当我尝试在 GIMP 中打开此图像时,它也显示为黑色,与 ImageSharp 中相同, 在此处输入图像描述

在此处输入图像描述

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.只是对如何显示此 tif 感到困惑,ImageSharp 甚至无法将其识别为 16 位灰度,因此我试图找到一种使用 C# 显示此图像的方法,如果可以的话,我想使用 MagickImage。 It's coming from a microscope.它来自显微镜。

any help would be greatly appreciated任何帮助将不胜感激

For 16 bit grayscale, we may use auto-level option:对于 16 位灰度,我们可以使用auto-level选项:

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).假设您的 PC 仅支持 8 位灰度显示(在 RGB 格式中,当每个像素的 r=g=b 时,灰度显示为每个红色、绿色和蓝色 8 位)。

When we want to display a 16 bits image, we have to convert it to 8 bits first.当我们要显示 16 位图像时,我们必须先将其转换为 8 位。
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).查看器使用的默认转换是获取每 16 位的高 8 位,并忽略低 8 位(相当于将所有像素除以 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.例如,如果像素范围约为 [0, 255](或说 [0, 1000]),则图像将非常暗或完全黑色。
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).查找最小和最大像素值,并应用比例和偏移量,使最小值为0 (黑色),最大值为255 [或 65535,对于 16 位](白色)。


For correctly handling 16 bit images, we have to install Magick.NET- Q16 .为了正确处理 16 位图像,我们必须安装 Magick.NET- Q16
See the following post for details.有关详细信息,请参阅以下帖子

For testing, I used the oldest release of MagickViewer .为了测试,我使用了最旧的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);
        }
        //===========================================================================================
    }
    //==============================================================================================
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM