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!

anthonypliu
źródło

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).

CRice
źródło
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));
INT_24h
źródło
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);
    }
Austin
źródło
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");
        }
    }
}
Nishant Kumar
źródło
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ę.

Milan Sheth
źródło
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();
    }
}
Yogesh Bhokare
źródło
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.

abhishek
źródło
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.

afranz409
źródło
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;
    }

}
MOHD KHALID
źródło
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