简体   繁体   English

将Base64字符串转换为GIF图像

[英]Converting Base64 string to GIF image

For a side project I am trying to make a simple executable that takes 2 arguments: 对于辅助项目,我试图制作一个带有2个参数的简单可执行文件:

  1. Text file path (contains a Base64 encoded animated GIF) (example base.txt) 文本文件路径(包含Base64编码的动画GIF)(例如base.txt)
  2. Name of the GIF to export (example hello.gif) 要导出的GIF的名称(示例hello.gif)

The way I am thinking it should all go is this: 我认为应该全部采用的方式是:

  1. It opens and reads the data from the file 它打开并从文件中读取数据
  2. It takes the data and decodes the Base64 string 它获取数据并解码Base64字符串
  3. It then saves the data as an animated GIF 然后将数据另存为动画GIF

Now of course there are some intermediate steps that need to happen but I don't think I need to cover that at the moment. 当然,现在需要执行一些中间步骤,但是我认为目前无需覆盖。

So in the end I am left with the following C# file which should do what I want. 所以最后我剩下了下面的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");
            }
        }
    }
}

This builds perfectly fine in MonoDevelop. 这在MonoDevelop中构建得很好。 But when I go to run the file (given the two arguments) it spits out the following exception: 但是,当我去运行文件时(考虑到两个参数),它会抛出以下异常:

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 

I have absolutely no idea what this is saying and all of my searches on Google have turned up blank so I now turn to Stack Overflow hoping that someone can help me with this. 我完全不知道这是什么意思,我在Google上的所有搜索都变成空白,所以现在转向Stack Overflow,希望有人可以帮助我。

Convert.FromBase64String requires that the input string be padded at the end with up to two = characters so that its total length (ignoring white-space characters) is a multiple of four. Convert.FromBase64String要求在输入字符串的末尾最多填充两个=字符,以便其总长度(忽略空格字符)为四的倍数。 Apparently, the program that created your base 64-encoded file omitted the trailing padding. 显然,创建基本64位编码文件的程序省略了尾随填充。

You need to append the missing padding characters yourself as necessary: 您需要根据需要自己添加缺少的填充字符:

// 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);

Note: Since Convert.FromBase64String ignores white-space characters, it's unnecessary to remove new-line characters. 注意:由于Convert.FromBase64String忽略空格字符,因此不必删除换行符。 (My thanks to EZI for pointing this out.) (我感谢EZI指出了这一点。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM