2015-01-18 2 views
1

Для стороннего проекта я пытаюсь сделать простой исполняемый файл, который принимает 2 аргумента:Преобразование Base64 строку GIF изображения

  1. путь текстовый файл (содержит кодировкой Base64 анимированный GIF) (пример base.txt)
  2. Название GIF для экспорта (например hello.gif)

Так я имею в виду, это все должны идти так:

  1. Это открывает и читает данные из файла
  2. Он принимает данные и декодирует строку Base64
  3. Затем он сохраняет данные в виде анимированного GIF

Теперь, конечно, есть некоторые промежуточные шаги, которые необходимо но я не думаю, что мне нужно это сделать на данный момент.

Так что в конце концов я остался со следующим файлом 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, надеясь, что кто-то может мне помочь.

+0

Это означает, что 'imageData' не содержит допустимую строчную кодировку с базой 64. –

+0

Но он делает o.O. Все ранее существовавшие преобразователи могут легко считывать данные из файла. Возможно, что-то я делаю неправильно, читая его, что делает недействительной строку? –

+0

Перед выполнением этой строки вы можете отлаживать и видеть, что значения 'imageData.Length',' imageData [0] ',' imageData [1] ',' imageData [imageData.Length - 2] 'и' imageData [imageData.Length - 1] 'есть? –

ответ

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 за указание на это.)

Смежные вопросы