konwertowanie ciągu bazowego 64 na obraz i zapisywanie go


139

Oto mój kod:

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();
            }
        }
}

Górna deklaracja imageUrl pobiera ciąg obrazu Base64 i chcę go przekonwertować na obraz. Myślę, że mój zestaw kodu działa tylko dla obrazów takich jak „www.mysite.com/test.jpg”, a nie dla ciągu Base64. Czy ktoś ma jakieś sugestie? Dzięki!

Odpowiedzi:


231

Oto przykład, możesz zmodyfikować metodę, aby akceptowała parametr ciągu. Następnie po prostu zapisz obiekt obrazu za pomocą 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;
}

Możliwe jest uzyskanie wyjątku, A generic error occurred in GDI+.gdy bajty reprezentują mapę bitową. Jeśli tak się dzieje, zapisz obraz przed usunięciem strumienia pamięci (nadal wewnątrz instrukcji using).


Ta metoda daje mi czarny prostokąt, masz jakiś pomysł?
— katmanco

57
Tak, to jest czarny piksel: R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw ==
— CRice

6
@katmanco Myślę, że jako przykład podano czarny piksel. Spróbuj zastąpić przykładowy ciąg base64 własnym ciągiem base64
— kallotec

2
Może być konieczne dodanie odwołania do biblioteki DLL System.Drawing
— Philip Rego,

1
@Bibin Czy próbowałeś zapisać obraz w instrukcji using?
— CRice

87

Możesz zapisać Base64 bezpośrednio do pliku:

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

Jest to doskonałe rozwiązanie w moim przypadku, gdy używałem mono w Linuksie i doświadczyłem dziwnego zachowania z gdi + w Image.Save. To rozwiązanie całkowicie omija Image / Gdi + (patrz stackoverflow.com/questions/35783690/… )
— Jeff Albrecht

1
Wypróbowałem zarówno to, jak i rozwiązanie @ CRice (używając Image.Save()). Oba działają, ale z jakiegoś powodu ta wersja zmniejsza rozmiar mojego pliku o 30% bez zauważalnej zmiany jakości obrazu
— Brad Mathews

31

Oto, z czym skończyłem.

    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
To dało mi A generic error occurred in GDI+opisany tutaj błąd . Przeniesienie image.Savewnętrza bloku using naprawiło to za mnie.
— JumpingJezza

11

Sugerowałbym za pośrednictwem 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
Jaka jest różnica między konwersją za pomocą mapy bitowej lub bez mapy bitowej? thx
— Amine Da.

6

W moim przypadku działa tylko z dwoma wierszami kodu. Przetestuj poniższy kod C #:

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

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

Otóż ​​to. Uprzejmie głosuj, jeśli naprawdę uważasz, że to rozwiązanie działa dla Ciebie. Z góry dziękuję.


1
To kopia mojej odpowiedzi (patrz poniżej stackoverflow.com/a/35160048/4190593 ) :)
— INT_24h,

-1, ponieważ dirPathmusi mieć @znak przed łańcuchem i..e. @"C:\myfolder\"albo musisz uciec przed ukośnikami w ciągu, np."C:\\myfolder\\"
— Marcus Parsons

powinieneś podać odniesienie do tej innej odpowiedzi, zamiast brać cały kredyt ...
— Arshi

6

Oto działający kod do konwersji obrazu z ciągu base64 na Imageobiekt i przechowywania go w folderze o unikalnej nazwie pliku:

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

W podobnym scenariuszu zadziałało dla mnie:

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

ImageTagId to identyfikator tagu obrazu ASP.


5

Jeśli masz ciąg danych binarnych zakodowanych w formacie Base64, powinieneś być w stanie wykonać następujące czynności:

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

Powinieneś być w stanie zapisać wynikową tablicę do pliku.


To nie działa. Po prostu konwertuje ciąg base64 na jego binarny odpowiednik. Zapisanie tego do pliku z rozszerzeniem graficznym nie czyni go obrazem.
— elliotwesoff

1
Nie? Przepraszam, to jest niepoprawne . Konwersja ciągu Base64 na jego binarny odpowiednik nie powoduje przekształcenia go w obraz. (Dzięki @elliotwesoff za wskazanie tego!) I dlaczego wspominasz o danych binarnych ? To pytanie w żaden sposób nie wspomina o binarnym , ani nawet o tym, jak go przekonwertować.
— Momoro

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
Chociaż ten kod może rozwiązać problem PO, najlepiej jest dołączyć wyjaśnienie, w jaki sposób Twój kod rozwiązuje problem PO. W ten sposób przyszli odwiedzający mogą uczyć się z Twojego postu i zastosować go do własnego kodu. SO nie jest usługą programistyczną, ale źródłem wiedzy. Ponadto istnieje większe prawdopodobieństwo, że wysokiej jakości, kompletne odpowiedzi zostaną poparte. Te funkcje, wraz z wymogiem, aby wszystkie posty były samodzielne, są jednymi z mocnych stron SO jako platformy, która odróżnia ją od forów. Możesz edytować, aby dodać dodatkowe informacje i / lub uzupełnić wyjaśnienia o dokumentację źródłową.
— ysf
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.