将Base64字符串转换为GIF图像

时间:2015-01-18 22:17:10

标签: c# image mono base64 animated-gif

对于一个辅助项目,我试图创建一个带有两个参数的简单可执行文件:

  1. 文本文件路径(包含Base64编码的动画GIF)(示例base.txt)
  2. 要导出的GIF的名称(例如hello.gif)
  3. 我认为应该这样做的方式是:

    1. 它打开并从文件中读取数据
    2. 它获取数据并解码Base64字符串
    3. 然后将数据保存为动画GIF
    4. 现在当然有一些中间步骤需要发生,但我认为我现在不需要介绍。

      所以最后我留下了下面的C#文件,它应该做我想要的。

      using System;
      using System.Drawing;
      using System.Text;
      using System.IO;
      
      namespace Base642Img
      {
          class MainClass
          {
              public static void Main (string[] args)
              {
                  if (args.Length == 2) {
                      byte[] buffer;
                      String imageData;
                      FileStream fileStream = new FileStream (args [0], FileMode.Open, FileAccess.Read);
      
                      try {
                          int length = (int)fileStream.Length;
                          buffer = new byte[length];
                          int count;
                          int sum = 0;
      
                          while ((count = fileStream.Read (buffer, sum, length - sum)) > 0) {
                              sum += count;
                          }
                      } finally {
                          fileStream.Close();
                      }
      
                      try{
                          imageData = Encoding.UTF8.GetString (buffer, 0, buffer.Length);
                          imageData = imageData.Replace (System.Environment.NewLine, "");
      
                          byte[] imageBytes = System.Convert.FromBase64String (imageData);
      
                          MemoryStream ms = new MemoryStream (imageBytes, 0, imageBytes.Length);
                          ms.Write (imageBytes, 0, imageBytes.Length);
      
                          Image image = Image.FromStream (ms, true);
                          image.Save (args [1], System.Drawing.Imaging.ImageFormat.Gif);
                      } catch (Exception e) {
                          Console.WriteLine (e.ToString ());
                      }
                  } else {
                      Console.WriteLine ("Incorrect number of arguments");
                  }
              }
          }
      }
      

      这在MonoDevelop中构建完美。但是当我去运行文件时(给定两个参数),它会吐出以下异常:

      System.FormatException: Invalid length.
        at (wrapper managed-to-native) System.Convert:InternalFromBase64String (string,bool)
        at System.Convert.FromBase64String (System.String s) [0x00000] in <filename unknown>:0 
        at Base642Img.MainClass.Main (System.String[] args) [0x00000] in <filename unknown>:0 
      

      我完全不知道这是什么意思,我在Google上的所有搜索都显示为空白,所以我现在转向Stack Overflow,希望有人可以帮助我。

1 个答案:

答案 0 :(得分:2)

Convert.FromBase64String要求输入字符串最后用最多两个=字符填充,以使其总长度(忽略空白字符)是四的倍数。显然,创建基本64位编码文件的程序省略了尾随填充。

您需要根据需要自己添加缺少的填充字符:

// using System.Collections.Generic;
// using System.Linq;

string imageData = File.ReadAllText(args[0]);
HashSet<char> whiteSpace = new HashSet<char> { '\t', '\n', '\r', ' ' };
int length = imageData.Count(c => !whiteSpace.Contains(c));
if (length % 4 != 0)
    imageData += new string('=', 4 - length % 4); // Pad length to multiple of 4.
byte[] imageBytes = Convert.FromBase64String(imageData);
MemoryStream ms = new MemoryStream(imageBytes);
Image image = Image.FromStream(ms, true);
image.Save(args[1], System.Drawing.Imaging.ImageFormat.Gif);

注意:由于Convert.FromBase64String忽略空格字符,因此无需删除换行符。 (感谢EZI指出这一点。)