如何将TIFF图像的字节数组转换为System.Drawing.Image对象?

6

我有一个byte[]数组,其内容表示一个TIFF文件(即,如果我使用BinaryWriter对象直接将这些字节写入文件,它就形成了一个完全有效的TIFF文件),我想将其转换为System.Drawing.Image对象,以便稍后进行操作(输入到多页TIFF对象中)。

我遇到的问题是,常用于此任务的代码:

    public Image byteArrayToImage(byte[] byteArrayIn)
    {
        MemoryStream ms = new MemoryStream(byteArrayIn);
        Image returnImage = Image.FromStream(ms, true);
        return returnImage;
    }

对我没用。上面的方法第二行调用Image.FromStream方法时在运行时失败,显示:

Parameter Not Valid

我认为问题出在这是一个TIFF文件,但我不知道如何使FromStream方法接受这一事实。

如何将TIFF图像的字节数组转换为图像对象?

此外,正如我所说,最终目标是拥有一个表示多页TIFF文件的字节数组,其中包含我现在拥有字节数组对象的TIFF文件。如果有更好的方法来完成这个任务,我很乐意尝试。

3个回答

3

好的,我找到了问题所在,它与我询问的代码部分无关。数据被传递为字符串,我将其转换为字节数组(这是一个测试装置,我试图模拟主应用程序中获得的字节数组),然后将其转换为MemoryStream,再从中创建Image。

我没有意识到的是,该字符串是Base64编码的。调用Convert.FromBase64String()会将其转换为字节数组,这会导致Image.FromStream()方法失效。

所以基本上归结为我的一个愚蠢错误。但是,上面的代码仍然有用,而且这个页面可能会成为谷歌搜索结果,告诉其他人如何避免这个错误。

另外,我在这里找到了一种从我的字节数组构建Multi-Page TIFF的简单方法here


2

编辑:下面的假设是不正确的,稍后我有机会启动我的 IDE 并测试了写和不写两种情况,两者都正确地填充了 MemoryStream。

我认为您需要先将数据写入到 MemoryStream 中。

如果我记得正确的话,应该是这样的:

MemoryStream ms = new MemoryStream(byteArrayIn);

创建指定大小的内存流。

然后您需要将字节数组内容写入内存流中:

ms.Write(byteArrayIn, 0, byteArrayIn.Length);

看看那是否修复了它。


为了获得更好的性能,只需设置ms.Length和ms.Position而不是再次调用ms.Write。 - Lilith River

1
所有这些都是帮助我解决问题的线索,我的问题与该问题相同。因此,我想发布我得出的解决方案,因为这些有用的线索。感谢迄今为止发布的所有提示!
正如Time Saunders在他的答案中发布的那样,编写将字节实际写入内存流的方法是必不可少的。这是我的第一个错误。
然后我的数据也是坏的TIFF数据,但在我的情况下,我在图像数据开头多了一个额外的字符13。一旦我删除它,一切就对我运行良好。
当我阅读一些基本的TIFF文件格式规范时,发现TIFF文件必须以II或MM(值为73或77的两个字节)开头。 II表示使用小端字节顺序(“Intel字节顺序”)。 MM表示使用大端(“Motorola字节顺序”)。接下来的两个字节是一个两个字节的整数值(= .NET中的Int16),值为42,二进制101010。
因此,正确的TIFF字节流应以以下十进制字节值开始:73、73、42、0或77、77、0、42。我鼓励经历过我们遇到的相同问题的任何人检查您的TIFF数据字节流,并确保您的数据是有效的TIFF数据!
感谢Schnapple和Tim Saunders!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接