перетворення базового 64 рядка в зображення та збереження його


132

Ось мій код:

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. У когось є якісь пропозиції? Дякую!

Відповіді:


218

Ось приклад, ви можете змінити метод, щоб прийняти параметр рядка. Потім просто збережіть об’єкт зображення за допомогою 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+.коли байти представляють растрові карти. Якщо це відбувається, збережіть зображення перед тим, як розпоряджатися потоком пам’яті (поки все ще знаходиться у використанні оператора).


Цей метод дає мені чорний прямокутник, у вас є ідеї?
катманко

54
Так, це чорний піксель: R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAAAAAAABAAEAAATATAEAOw ==
CRice

6
@katmanco Я вважаю, що чорний піксель наводився як приклад. Спробуйте замінити приклад рядок base64 на власний рядок base64
kallotec

2
Можливо, вам потрібно буде додати посилання на System.Drawing DLL
Philip Rego

1
@Bibin Ви намагалися зберегти зображення всередині оператора use?
CRice

83

Ви можете зберегти Base64 безпосередньо у файл:

string filePath = "MyImage.jpg";
File.WriteAllBytes(filePath, Convert.FromBase64String(base64imageString));

Це відмінне рішення в моєму випадку, коли я використовував моно в 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всередину за допомогою блоку зафіксувало це для мене.
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);

Ви повинні мати можливість записати отриманий масив у файл.


Це не працює. Він просто перетворює рядок 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
Хоча цей код може вирішити проблему ОП, найкраще включити пояснення, як ваш код вирішує проблему ОП. Таким чином майбутні відвідувачі можуть дізнатисясь із вашої публікації та застосувати її до власного коду. ТАК - це не програма кодування, а ресурс для знань. Крім того, швидше за все буде запрошено високу якість, повну відповідь. Ці функції, поряд з вимогою, що всі повідомлення є автономними, є деякою сильною стороною SO як платформи, що відрізняє її від форумів. Ви можете редагувати, щоб додати додаткову інформацію та / або доповнити свої пояснення джерельною документацією.
ysf
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.