преобразование строки base 64 в изображение и сохранение его

134

Вот мой код:

protected void SaveMyImage_Click(object sender, EventArgs e)
        {
            string imageUrl = Hidden1.Value;
            string saveLocation = Server.MapPath("~/PictureUploads/whatever2.png") ; 


            HttpWebRequest imageRequest = (HttpWebRequest)WebRequest.Create(imageUrl);
            WebResponse imageResponse = imageRequest.GetResponse();

            Stream responseStream = imageResponse.GetResponseStream();

            using (BinaryReader br = new BinaryReader(responseStream))
            {
                imageBytes = br.ReadBytes(500000);
                br.Close();
            }
            responseStream.Close();
            imageResponse.Close();

            FileStream fs = new FileStream(saveLocation, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs);
            try
            {
                bw.Write(imageBytes);
            }
            finally
            {
                fs.Close();
                bw.Close();
            }
        }
}

Верхнее объявление imageUrl принимает строку изображения Base64, и я хочу преобразовать ее в изображение. Я думаю, что мой набор кода работает только для изображений типа «www.mysite.com/test.jpg», а не для строки Base64. У кого-нибудь есть предложения? Спасибо!

anthonypliu
источник

Ответы:

220

Вот пример, вы можете изменить метод для приема строкового параметра. Затем просто сохраните объект изображения с помощью image.Save (...) .

public Image LoadImage()
{
    //data:image/gif;base64,
    //this image is a single pixel (black)
    byte[] bytes = Convert.FromBase64String("R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==");

    Image image;
    using (MemoryStream ms = new MemoryStream(bytes))
    {
        image = Image.FromStream(ms);
    }

    return image;
}

Если A generic error occurred in GDI+.байты представляют растровое изображение, возможно возникновение исключения . Если это происходит, сохраните изображение перед удалением потока памяти (пока все еще внутри оператора using).

CRice
источник
Этот метод дает мне черный прямоугольник, у вас есть идеи?
katmanco 01
54
Да, это черный пиксель: R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw ==
CRice 01
6
@katmanco Я бы подумал, что черный пиксель был приведен в качестве примера. Попробуйте заменить пример строки base64 своей собственной строкой base64
kallotec
2
Возможно, вам потребуется добавить ссылку на DLL System.Drawing
Филип Рего
1
@Bibin вы пытались сохранить изображение внутри оператора using?
CRice
84

Вы можете сохранить Base64 прямо в файл:

string filePath = "MyImage.jpg";
File.WriteAllBytes(filePath, Convert.FromBase64String(base64imageString));
INT_24h
источник
Это отличное решение в моем случае, когда я использовал моно в Linux и столкнулся с некоторыми странностями с gdi + в Image.Save. Это решение полностью обходит изображение / Gdi + (См stackoverflow.com/questions/35783690/... )
Джефф Albrecht
1
Я пробовал и это, и решение @ CRice (используя Image.Save()). Оба работают, но по какой-то причине эта версия уменьшает размер моего файла на 30% без заметного изменения качества изображения
Брэд Мэтьюз
31

Вот что я в итоге сделал.

    private void SaveByteArrayAsImage(string fullOutputPath, string base64String)
    {
        byte[] bytes = Convert.FromBase64String(base64String);

        Image image;
        using (MemoryStream ms = new MemoryStream(bytes))
        {
            image = Image.FromStream(ms);
        }

        image.Save(fullOutputPath, System.Drawing.Imaging.ImageFormat.Png);
    }
Остин
источник
7
Это дало мне A generic error occurred in GDI+описанную ошибку здесь . Перемещение image.Saveвнутри блока using исправило это для меня.
JumpingJezza
11

Я бы предложил через Bitmap:

public void SaveImage(string base64)
{
    using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(base64)))
    {
        using (Bitmap bm2 = new Bitmap(ms))
        {
            bm2.Save("SavingPath" + "ImageName.jpg");
        }
    }
}
Нишант Кумар
источник
2
в чем разница между преобразованием через растровое изображение или без него? thx
Амин Да.
6

В моем случае это работает только с двумя строками кода. Проверьте приведенный ниже код C #:

String dirPath = "C:\myfolder\";
String imgName = "my_mage_name.bmp";

byte[] imgByteArray = Convert.FromBase64String("your_base64_string");
File.WriteAllBytes(dirPath + imgName, imgByteArray);

Вот и все. Пожалуйста, проголосуйте, если вы действительно считаете, что это решение работает для вас. Заранее спасибо.

Милан Шет
источник
1
Это копия моего ответа (см. Ниже stackoverflow.com/a/35160048/4190593 ) :)
INT_24h
-1, потому dirPathчто @перед строкой i..e должен стоять знак. @"C:\myfolder\"или вам нужно избегать обратных косых черт в строке, то есть"C:\\myfolder\\"
Маркус Парсонс
вы должны дать ссылку на этот другой ответ вместо того, чтобы принимать всю заслугу ....
Арши
6

Вот рабочий код для преобразования изображения из строки base64 в Imageобъект и сохранения его в папке с уникальным именем файла:

public void SaveImage()
{
    string strm = "R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"; 

    //this is a simple white background image
    var myfilename= string.Format(@"{0}", Guid.NewGuid());

    //Generate unique filename
    string filepath= "~/UserImages/" + myfilename+ ".jpeg";
    var bytess = Convert.FromBase64String(strm);
    using (var imageFile = new FileStream(filepath, FileMode.Create))
    {
        imageFile.Write(bytess, 0, bytess.Length);
        imageFile.Flush();
    }
}
Йогеш Бхокаре
источник
5

В аналогичном сценарии у меня сработало следующее:

byte[] bytes = Convert.FromBase64String(Base64String);    
ImageTagId.ImageUrl = "data:image/jpeg;base64," + Convert.ToBase64String(bytes);

ImageTagId - это идентификатор тега изображения ASP.

Абхишек
источник
5

Если у вас есть строка двоичных данных в кодировке Base64, вы должны иметь возможность делать следующее:

byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);

Вы должны иметь возможность записать полученный массив в файл.

afranz409
источник
Это не работает. Он просто преобразует строку base64 в ее двоичный эквивалент. Запись этого в файл с расширением изображения не делает его изображением.
elliotwesoff
1
Нет? Простите, это неверно . Преобразование строки Base64 в ее двоичный эквивалент не делает ее изображением. (Спасибо @elliotwesoff за указание на это!) И почему вы упоминаете двоичные данные ? В этом вопросе ни в коей мере не упоминается двоичный файл или даже то, как его преобразовать.
Моморо
0
public bool SaveBase64(string Dir, string FileName, string FileType, string Base64ImageString)
{
    try
    {
        string folder = System.Web.HttpContext.Current.Server.MapPath("~/") + Dir;
        if (!Directory.Exists(folder))
        {
            Directory.CreateDirectory(folder);
        }

        string filePath = folder + "/" + FileName + "." + FileType;
        File.WriteAllBytes(filePath, Convert.FromBase64String(Base64ImageString));
        return true;
    }
    catch
    {
        return false;
    }

}
МОХД ХАЛИД
источник
2
Хотя этот код может решить проблему OP, лучше всего включить объяснение того, как ваш код решает проблему OP. Таким образом, будущие посетители могут узнать из вашего сообщения и применить его к своему собственному коду. SO - это не сервис кодирования, а ресурс знаний. Кроме того, больше шансов получить качественные и полные ответы. Эти функции, наряду с требованием, чтобы все сообщения были автономными, являются одними из сильных сторон SO как платформы, которые отличает ее от форумов. Вы можете редактировать, чтобы добавить дополнительную информацию и / или дополнить свои пояснения исходной документацией.
ysf