首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >字节数组末尾的大量0值

字节数组末尾的大量0值
EN

Stack Overflow用户
提问于 2016-03-30 20:57:54
回答 2查看 1.4K关注 0票数 2

我使用BitMiracle的LibTiff.Net读取位图图像,并返回作为Base64String嵌入文件中的TIFF byte[]。我注意到Base64字符串最终比我预期的要长得多,它的尾部是大量的'A‘字符。调试时,我看到LibTiff返回给我的LibTiff在末尾有几千个值,这些值似乎不是映像本身的必要部分(据我所知)。

我在这里使用BitMiracle的示例代码来转换:https://bitmiracle.github.io/libtiff.net/html/075f57db-d779-48f7-9fd7-4ca075a01599.htm

不过,我不太明白在byte[]的末尾会产生什么“垃圾”。有什么想法吗?

编辑以添加代码- GetTiffImageBytes()在上面的链接中:

代码语言:javascript
复制
public void GenImage()
      using (System.Drawing.Image frontImage = System.Drawing.Image.FromStream(file))//;
            {
                file.Close();

                //Draw something
                b = new Bitmap(frontImage);
                Graphics graphics = Graphics.FromImage(b);
                graphics.DrawString(data1, (Font)GlobalDict.FontDict["font1"], Brushes.Black, 200, 490);
                graphics.DrawString(data2, (Font)GlobalDict.FontDict["font2"], Brushes.Black, 680, 400);

            }
            //Convert to TIF - requires BitMiracle.LibTiff.Classic
            byte[] tiffBytes = GetTiffImageBytes(b, false);

            return tiffBytes;
            }

上述情况是由以下方面提出的:

代码语言:javascript
复制
  byte[] aFrontImage = MiscTools.GenImage(somestuff);

  fileXML.WriteLine("    <FrontImage>" + System.Convert.ToBase64String(aFrontImage, 0, aFrontImage.Length) + "</FrontImage>");

所有的事情说和做,它的功能很好,结果的图像是可读的应用程序。我只是想缩小尺寸,因为其中一些文件可能有数万张图片。我有一些旧的示例文件是通过另一个大小大致相同的字符串手工创建的Base64字符串创建的,保存了我认为是垃圾的所有尾随字节。

正如有人评论的那样,一种选择可能是在转换之前读取byte[]并从末尾删除所有的0值,但我正在试图弄清楚为什么会发生这种情况。

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-19 13:30:08

这个问题很可能是在链接源示例中发现的

代码语言:javascript
复制
return ms.GetBuffer();

对于一个MemoryStream,这将返回整个底层数组,即使您还没有真正使用该数组。如果您编写足够的数据来填充缓冲区,这个缓冲区将被调整为一个更大的缓冲区,但是它不会扩展到只覆盖所需的大小,每次都会增长到以前大小的两倍。此外,您还拥有一个Length属性,该属性将指示实际使用了多少此数组。

这类似于List<T>的容量,当您填充当前的容量时,它的大小也会翻倍。Count属性将指示列表中实际有多少项。

修复很容易,请用以下代码替换上面的代码:

代码语言:javascript
复制
return ms.ToArray();

这将创建一个新的数组,该数组足够大,足以包含实际写入内存流的字节,并将缓冲区的内容(适合并计数的部分)复制到其中。

要验证缓冲区是否大于需要,可以运行以下简单代码:

代码语言:javascript
复制
var ms = new MemoryStream();
Console.WriteLine("GetBuffer: " + ms.GetBuffer().Length);
Console.WriteLine("ToArray: " + ms.ToArray().Length);
ms.WriteByte(0);
Console.WriteLine("GetBuffer: " + ms.GetBuffer().Length);
Console.WriteLine("ToArray: " + ms.ToArray().Length);

这将产生以下结果:

代码语言:javascript
复制
GetBuffer: 0
ToArray: 0
GetBuffer: 256
ToArray: 1

如您所见,当只向其写入1字节时,初始缓冲区大小增加到256字节。在此之后,每次您到达当前大小时,它都会加倍。

.NET Fiddle

票数 3
EN

Stack Overflow用户

发布于 2016-04-04 13:34:29

现在,我只是“修复”了事实之后的问题,并创建了一个方法,我调用了每个图像:

代码语言:javascript
复制
        private static byte[] fixImageByteArray(byte[] inByte)  // Fix issue with garbage suffix data - reduces image byte[] size by roughly half.
    {
        int newByteBaseLength = inByte.Length - 1;  
        while (inByte[newByteBaseLength] == 0)
        {
            --newByteBaseLength;
        }

        float newByteModifiedLength = ((inByte.Length - newByteBaseLength) * 0.1f) + 0.5f;  // When using newByteBaseLength + 1, some TIFF Tag data was getting lost.  This seems to resolve the issue.

        int newByteModifiedLengthAsInt = (int)newByteModifiedLength;

        byte[] outByte = new byte[newByteBaseLength + newByteModifiedLengthAsInt];
        Array.Copy(inByte, outByte, newByteBaseLength + newByteModifiedLengthAsInt);

        return outByte;
    }

编辑:我修改了变量名,使之更有意义。我发现用旧的方式(使用newByteBaseLength + 1)来调整数组的大小会对TIFF标记造成一些损害。通过使用一种效率稍低的方法,图像大小仍然显着减少,但标记保持不变。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36319597

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档