【问题标题】:Writing an image to a text file as binary data C#将图像作为二进制数据写入文本文件 C#
【发布时间】:2010-10-27 11:31:57
【问题描述】:

我需要创建一个文件,将图像作为文本嵌入到某些记录中。我在将图像写为文本时遇到了一些麻烦。我正在做的是将图像作为字节数组从 SQL 数据库(图像类型)收集,然后我通过遍历每个字节并将该字节的 ASCII 等效于文件写入该图像到文本文件。

在将该图像写入文本文件之前,我必须将其转换为 CCITT4 格式的 TIFF(以前是 jpeg)。为了仔细检查这是否正确完成,我还将流保存为 TIFF 并在“AsTiffTagViewer”中查看它,这表明压缩是正确的。我能够在适当的查看器中查看 tiff;但是,从文件中收集文本时,我无法查看图像。

代码如下:

byte[] frontImage = (byte[])imageReader["front_image"];
MemoryStream frontMS = new MemoryStream(frontImage);
Image front = Image.FromStream(frontMS);
Bitmap frontBitmap = new Bitmap(front);
Bitmap bwFront = ConvertToBitonal(frontBitmap);
bwFront.SetResolution(200, 200);
MemoryStream newFrontMS = new MemoryStream();
bwFront.Save(newFrontMS, ici, ep);
bwFront.Save("c:\\Users\\aarong\\Desktop\\C#DepositFiles\\" + checkReader["image_id"].ToString() + "f.tiff", ici, ep);
frontImage = newFrontMS.ToArray();   
String frontBinary = toASCII(frontImage); 

private String toASCII(byte[] image)
{
    String returnValue = "";
    foreach (byte imageByte in image)
    {
        returnValue += Convert.ToChar(imageByte);
    }
    return returnValue;
}   

写入文件的是frontBinary。有谁知道出了什么问题?保存的 tiff 是正确的,但完全相同的字节数组,当写入 ASCII 文本时,写入不正确。

谢谢。

编辑 已通过使用 BinaryWriter(byte[]) 将图像正确地写入文本来纠正此问题。谢谢大家的帮助!

【问题讨论】:

    标签: c# image stream


    【解决方案1】:

    一方面,ASCII 只有七位。但是,我不相信您的代码实际上使用 ASCII。它隐含地使用了 ISO-8859-1。

    从不将文本视为二进制,反之亦然。它会总是导致问题。

    将二进制转换为 ASCII 文本的最佳方法是使用 Base64:

    string text = Convert.ToBase64String(frontImage);
    byte[] data = Convert.FromBaseString(text);
    

    另请注意,如果您的代码确实工作,它仍然会非常低效 - 请阅读StringBuilders,然后考虑您的代码与

    Encoding.GetEncoding(28591).GetString(data);
    

    但是,base64 绝对是在文本和二进制数据之间进行无损转换的方法。当然,您需要将其转换回二进制文件才能再次查看 TIFF。

    请注意,您尚未展示如何保存或加载数据 - 您可能也遇到了问题。事实上,我怀疑如果您能够准确地保存字符串,那么您可能很幸运并保存了数据,具体取决于您正在使用它做什么......但是使用 base64无论如何。

    【讨论】:

    • 嗨乔恩,非常感谢您的解释。还要感谢有关 StringBuilders 的信息...我肯定会使用这些信息,而不是我不必要的低效串联。我会尽快尝试您的建议,并会告诉您进展如何。
    • 嗨乔恩。我尝试了 Base64 字符串,它确实有效。我能够将图像写入文件并在读取文件时再次生成图像。感谢您的帮助,我相信您的解释会帮助其他有类似问题的人。 :)
    • 你好,乔恩。我将文件发送给的供应商刚刚告诉我 base64 不是正确的格式,它应该是“英特尔格式”。我的联系人告诉我,文本应该以“II”开头,这是我使用旧方法时的开头。如果我回到旧方法,文本仍然不正确。我正在使用 StreamWriter 对象来实际写入文件,并且我做了一些研究,说也许 BinaryWriter 是要走的路。也许这是一个潜在的问题?
    • 看看你能不能得到一个绝对精确的文件格式——不仅仅是名字,还有完整的规范。如果它是一个 text 文件,那么它不应该包含任意位的二进制数据。
    • 我确实有确切的规格。它指出“所有字符和符号必须使用 8 位 EBCDIC 编码表示,图像数据字段除外,它是二进制数据。”它进一步指出,图像必须是 TIFF 6.0,采用 CCITT4 压缩,当我将图像保存到文件时,我测试它是正确的。也许您之前所说的从数据库中获取图像是不正确的?也许我在加载数据时在某处丢失了数据。
    【解决方案2】:

    您使用文本而不是二进制文件是否有特定原因?

    在文本文件中存储二进制数据总是一个坏主意,因为编码可能会将字节转换为另一种表示形式,并且换行等特殊字符也可能会被特殊处理和转换。

    要么将数据作为字节数组存储在二进制文件中,要么使用正确的二进制到 ascii 转换,如 Jon 的 Base64 提议,或者也可以使用逗号分隔的十六进制值列表。

    【讨论】:

      【解决方案3】:

      如果您只将图像数据写入文件,则根本不应该将其写入为文本,而应写入二进制数据。

      如果您在文件中混合使用文本和二进制数据,则不应将二进制数据转换为文本。它可能适用于一些特定的编码来来回转换,但它肯定不适用于任何编码来将其转换为 unicode 字符(使用Convert.ToChar)。

      反过来做。使用正确的Encoding 对象的GetBytes 方法将文本编码为二进制数据,这样您就只有二进制数据可以写入文件。

      【讨论】:

      • 使用base64(或类似的——例如,你可以使用base16)将二进制数据转换为文本很好。听起来这个输出必须是另一个工具可以加载的记录格式 - 这表明他不能真正定义整个文件格式,正如将所有内容更改为二进制时所暗示的那样。
      【解决方案4】:

      您可能正在以 Unicode 格式读取数据库,这将改变图像中的一些二进制值。

      您可以使用 System.IO.File 类上的方法来读取/保存为二进制和文本。这些可能有助于与上述 Base64 选项一起使用。

      【讨论】:

        【解决方案5】:

        获取二进制数据并将其转换为文本数据的一种方法是使用 StreamReader 并提供所需的编码。就像上面提到的 Jon 一样,使用 ASCII 是不明智的,但如果有人想要将二进制流式传输到其他文本编码,这里有一些代码可以做到。

        public static String GetString(System.IO.Stream inStream)
        {
            string str = string.Empty;
            using (StreamReader reader = new StreamReader(inStream, System.Text.ASCIIEncoding.ASCII)) // or any other encoding.
            {
                str = reader.ReadToEnd();
            }
            return str;
        }
        

        【讨论】:

        • 不,这仍然是一个非常糟糕的主意 - 因为文本和二进制数据不能像那样很好地结合在一起,尤其是 ASCIIEncoding 会清除每个字节的最高位。
        • 我只是把他要求的二进制数据转换为 ascii 的东西给了他,而不是对目的或最终结果做出判断。
        • 然而,如果我知道它会丢失数据(甚至没有说它会发生),我认为给某人确切的要求并不是一个好主意。显然,这与 OP 的更大目标背道而驰。
        • 希望保留无用或碎屑的帖子是可以理解的,因此,我将清理这篇帖子以展示如何将任何二进制流传输到文本编码,诚然 ascii 在这种情况下很糟糕。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-06
        • 1970-01-01
        • 2020-10-30
        • 1970-01-01
        • 2017-01-26
        相关资源
        最近更新 更多