【问题标题】:How to set bit depth in Magick.NET Read如何在 Magick.NET 中设置位深度 Read
【发布时间】:2018-12-26 23:48:37
【问题描述】:

MagickImage.Read() 函数读取二进制文件时如何指定位深度?

我有一个由 8 位灰度值表示的 1024x1024 图像(总文件长度 = 1024x1024 = 1048576 字节)。使用 ImageMagick v.7.0.8-7 Q16 x64,我可以使用转换文件

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

当我尝试使用 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;
}

我得到了错误

消息:ImageMagick.MagickCorruptImageErrorException:意外 end-of-file '': 没有这样的文件或目录@ 错误/gray.c/ReadGRAYImage/241

表示程序已读取文件末尾。我已经确认 Magick.NET 正在恢复到 16 位深度,而不是我想要的 8 位深度。我可以使用 settings.Height = 512 而不是 1024 来读取文件,这给了我灰度图像的压缩版本。

我从Memory consumption in Magick.NET 了解到,Magick.NET Q16 以 16 位精度将像素存储在内存中;我对此很好,但似乎不应该排除 8 位读取功能。

如何强制 Magick.NET Q16 读取 8 位深度的像素?

【问题讨论】:

  • 您是否尝试过在NewImage 之前移动您设置深度的位置?我不知道Magick.Net,但也许应该是settings.Depth=8;
  • 查看文档,也许您需要使用 github.com/dlemstra/Magick.NET/blob/master/Documentation/… 的定义来告诉输出它应该是深度 8。
  • 感谢@fmw42;我确实尝试过settings.Depth=8;settings.SetDefine(MagickFormat.Gray, "depth", "8");,但都没有成功。我对ImageMagick的-define不是很了解;我想知道这是否能帮助我更好地理解 Magick.NET 的SetDefine()。你有什么好的资源吗?
  • 不,我拥有的唯一资源是我提供的链接。但是你可以在imagemagick.org/discourse-server/viewforum.php?f=27 提出这个问题,Magick.NET 的开发人员应该看到它并做出回应。给他时间,因为他还有另一份全职工作。您也可以在github.com/dlemstra/Magick.NET 发布问题,这可能是他找到它的更快方式。附言也许你对输出图像进行定义。
  • OK 就可以了。感谢您所做的所有工作,顺便说一句,这是我第一个而不是第 20 个 ImageMagick 问题的主要原因。

标签: c# imagemagick magick.net bit-depth


【解决方案1】:

我刚刚发布了 Magick.NET 7.6.0.0,它现在有更好的 API 来读取原始像素。您应该将代码更改为:

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);
}

【讨论】:

  • 您的解决方案是针对正好是一个字节的像素。有深度是12(12位)的情况,所以是1个半字节。每像素 12 位的解决方案是什么。
  • 我看到 12 位可以作为 16 位,但如果我这样做:new MagickImage( ...) 而不是 new MagickImage( ...),则数据被获取为 8 位(如果我保存它 - 我看到它变暗/不是原来的 16 位)。
  • @Eitan,我猜这是数据类型的问题。如何将一个 12 位的值映射成一个与像素亮度对应的数字? ImageMagick 可能不知道,所以 Magick.NET 也不知道。您可能需要将 12 位值转换为 ushort 数据类型,然后使用 var storageType = StorageType.ShortMagickImage.ReadPixels(uShortArray, pixelStorageSettings) 读入
【解决方案2】:

一种解决方法是使用Magick.NET Q8 版本而不是Magick.NET Q16。我使用程序Magick.NET Q8-AnyCPU 7.5.0.1成功读取了文件。

我仍然希望有一个解决方案可以让我仍然使用Magick.NET Q16,但这暂时有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-03
    • 1970-01-01
    • 2020-10-05
    • 2013-12-14
    • 2017-09-19
    • 2015-11-27
    • 1970-01-01
    相关资源
    最近更新 更多