字节数组末尾有大量 0 值
Large Number of 0 Values at End of Byte Array
我正在使用 BitMiracle 的 LibTiff.Net 读入位图图像和 return TIFF 字节 [] 作为 Base64String 嵌入到文件中。我注意到 Base64 字符串最终比我预期的要长很多,其尾端是大量 'A' 个字符。在调试时,我看到 LibTiff 对我来说 returning 的 byte[] 末尾有几千个 0 值,这些值似乎不是图像本身的必要部分(据我所知).
我在这里使用 BitMiracle 的示例代码进行转换:https://bitmiracle.github.io/libtiff.net/html/075f57db-d779-48f7-9fd7-4ca075a01599.htm
不过,我不太明白是什么导致 "garbage" 在 byte[] 的末尾。有什么想法吗?
编辑以添加代码 - GetTiffImageBytes() 在上面的 link 中:
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;
}
以上调用者:
byte[] aFrontImage = MiscTools.GenImage(somestuff);
fileXML.WriteLine(" <FrontImage>" + System.Convert.ToBase64String(aFrontImage, 0, aFrontImage.Length) + "</FrontImage>");
一切都说完了,它运行良好,我们的应用程序可以读取生成的图像。我只是想缩小尺寸,因为其中一些文件可能有数万张图片。我有一些较旧的示例文件,这些文件是通过另一种方法用一些 Base64 字符串手动创建的,这些字符串的大小大致相同,保存所有我认为是垃圾的尾部字节。
正如有人评论的那样,一种选择可能是只读取字节 [] 并在转换之前从末尾删除所有 0 值,但我试图弄清楚为什么会这样。
谢谢!
现在,我只是在事后处理 "fixing" 这个问题,并创建了一个方法来调用每张图片:
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 标签造成一些损坏。通过使用效率稍低的方法,图像大小仍然显着减小,但标签保持不变。
问题很可能是这个,发现在linked source example:
return ms.GetBuffer();
对于 MemoryStream
,这将 return 整个底层数组,即使您尚未实际使用该数组的所有内容。如果您写入足够多的内容来填充此缓冲区,该缓冲区将被调整为更大的缓冲区,但它不会扩展到仅覆盖所需的大小,它每次都会增长到以前大小的两倍。此外,您还有一个长度 属性,它将指示实际使用了多少该数组。
这类似于List<T>
的容量,每次填满当前容量,它的容量也会增加一倍。 Count
属性 将指示列表中实际有多少项。
修复很简单,将上面的代码行替换为:
return ms.ToArray();
这将创建一个新数组,其大小足以包含实际写入内存流的字节并将缓冲区的内容(适合和计数的部分)复制到其中。
要验证缓冲区是否大于需要,您可以运行这个简单的代码:
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);
这将输出:
GetBuffer: 0
ToArray: 0
GetBuffer: 256
ToArray: 1
如您所见,仅写入 1 个字节时的初始缓冲区大小增加到 256 个字节。之后每次达到当前尺寸时它都会翻倍。
我正在使用 BitMiracle 的 LibTiff.Net 读入位图图像和 return TIFF 字节 [] 作为 Base64String 嵌入到文件中。我注意到 Base64 字符串最终比我预期的要长很多,其尾端是大量 'A' 个字符。在调试时,我看到 LibTiff 对我来说 returning 的 byte[] 末尾有几千个 0 值,这些值似乎不是图像本身的必要部分(据我所知).
我在这里使用 BitMiracle 的示例代码进行转换:https://bitmiracle.github.io/libtiff.net/html/075f57db-d779-48f7-9fd7-4ca075a01599.htm
不过,我不太明白是什么导致 "garbage" 在 byte[] 的末尾。有什么想法吗?
编辑以添加代码 - GetTiffImageBytes() 在上面的 link 中:
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;
}
以上调用者:
byte[] aFrontImage = MiscTools.GenImage(somestuff);
fileXML.WriteLine(" <FrontImage>" + System.Convert.ToBase64String(aFrontImage, 0, aFrontImage.Length) + "</FrontImage>");
一切都说完了,它运行良好,我们的应用程序可以读取生成的图像。我只是想缩小尺寸,因为其中一些文件可能有数万张图片。我有一些较旧的示例文件,这些文件是通过另一种方法用一些 Base64 字符串手动创建的,这些字符串的大小大致相同,保存所有我认为是垃圾的尾部字节。
正如有人评论的那样,一种选择可能是只读取字节 [] 并在转换之前从末尾删除所有 0 值,但我试图弄清楚为什么会这样。
谢谢!
现在,我只是在事后处理 "fixing" 这个问题,并创建了一个方法来调用每张图片:
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 标签造成一些损坏。通过使用效率稍低的方法,图像大小仍然显着减小,但标签保持不变。
问题很可能是这个,发现在linked source example:
return ms.GetBuffer();
对于 MemoryStream
,这将 return 整个底层数组,即使您尚未实际使用该数组的所有内容。如果您写入足够多的内容来填充此缓冲区,该缓冲区将被调整为更大的缓冲区,但它不会扩展到仅覆盖所需的大小,它每次都会增长到以前大小的两倍。此外,您还有一个长度 属性,它将指示实际使用了多少该数组。
这类似于List<T>
的容量,每次填满当前容量,它的容量也会增加一倍。 Count
属性 将指示列表中实际有多少项。
修复很简单,将上面的代码行替换为:
return ms.ToArray();
这将创建一个新数组,其大小足以包含实际写入内存流的字节并将缓冲区的内容(适合和计数的部分)复制到其中。
要验证缓冲区是否大于需要,您可以运行这个简单的代码:
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);
这将输出:
GetBuffer: 0
ToArray: 0
GetBuffer: 256
ToArray: 1
如您所见,仅写入 1 个字节时的初始缓冲区大小增加到 256 个字节。之后每次达到当前尺寸时它都会翻倍。