Konvertieren einer Basis-64-Zeichenfolge in ein Bild und Speichern


131

Hier ist mein Code:

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

Die oberste imageUrl-Deklaration nimmt eine Base64-Bildzeichenfolge auf, und ich möchte sie in ein Bild konvertieren. Ich denke, mein Code funktioniert nur für Bilder wie "www.mysite.com/test.jpg", nicht für eine Base64-Zeichenfolge. Hat jemand ein paar Vorschläge? Vielen Dank!

Antworten:


216

In diesem Beispiel können Sie die Methode so ändern, dass sie einen Zeichenfolgenparameter akzeptiert. Speichern Sie dann einfach das Bildobjekt mit 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;
}

Es ist möglich, eine Ausnahme zu erhalten, A generic error occurred in GDI+.wenn die Bytes eine Bitmap darstellen. Speichern Sie in diesem Fall das Bild, bevor Sie den Speicherstrom entsorgen (während Sie sich noch in der using-Anweisung befinden).


Diese Methode gibt mir ein schwarzes Rechteck. Hast du eine Idee?
Katmanco

54
Ja, dies ist ein schwarzes Pixel: R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw ==
CRice

6
@katmanco Ich würde denken, dass das schwarze Pixel als Beispiel bereitgestellt wurde. Versuchen Sie, die Beispiel-Base64-Zeichenfolge durch Ihre eigene Base64-Zeichenfolge zu ersetzen
kallotec

2
Möglicherweise müssen Sie einen Verweis auf die System.Drawing DLL
Philip Rego

1
@Bibin Haben Sie versucht, das Bild in der using-Anweisung zu speichern?
CRice

82

Sie können Base64 direkt in einer Datei speichern:

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

Dies ist eine hervorragende Lösung in meinem Fall, in dem ich Mono unter Linux verwendet habe und mit gdi + in Image.Save ein merkwürdiges Verhalten festgestellt habe. Diese Lösung umgeht Image / Gdi + vollständig (siehe stackoverflow.com/questions/35783690/… )
Jeff Albrecht

1
Ich habe sowohl diese als auch die Lösung von @ CRice (mit Image.Save()) ausprobiert . Beide funktionieren, aber aus irgendeinem Grund verkleinert diese Version meine Dateigröße um 30%, ohne dass sich die Bildqualität ändert
Brad Mathews,

31

Hier ist, was ich am Ende gemacht habe.

    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
Dies gab mir einen hierA generic error occurred in GDI+ beschriebenen Fehler . Das Verschieben des Inneren des using-Blocks hat es für mich behoben. image.Save
JumpingJezza

10

Ich würde über Bitmap vorschlagen:

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
Was ist der Unterschied zwischen der Konvertierung über Bitmap oder ohne Bitmap? thx
Amine Da.

6

In meinem Fall funktioniert es nur mit zwei Codezeilen. Testen Sie den folgenden C # -Code:

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

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

Das ist es. Bitte stimmen Sie ab, wenn Sie wirklich feststellen, dass diese Lösung für Sie funktioniert. Danke im Voraus.


1
Es ist eine Kopie meiner Antwort (siehe unten stackoverflow.com/a/35160048/4190593 ) :)
INT_24h

-1 weil dirPathein @Zeichen vor dem String i..e haben muss. @"C:\myfolder\"oder Sie müssen den Backslashes in der Zeichenfolge entkommen, dh"C:\\myfolder\\"
Marcus Parsons

Sie sollten auf diese andere Antwort verweisen, anstatt die gesamte Anerkennung zu erhalten ...
Arshi

6

Hier ist Arbeitscode zum Konvertieren eines Bildes von einer base64-Zeichenfolge in ein ImageObjekt und zum Speichern in einem Ordner mit einem eindeutigen Dateinamen:

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

In einem ähnlichen Szenario funktionierte für mich Folgendes:

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

ImageTagId ist die ID des ASP-Image-Tags.


5

Wenn Sie eine Zeichenfolge von Binärdaten haben, die Base64-codiert ist, sollten Sie in der Lage sein, Folgendes zu tun:

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

Sie sollten in der Lage sein, das resultierende Array in eine Datei zu schreiben.


Das funktioniert nicht. Es konvertiert nur den base64-String in sein binäres Äquivalent. Wenn Sie das in eine Datei mit einer Bilderweiterung schreiben, wird es nicht zu einem Bild.
Elliotwesoff

1
Nein? Es tut mir leid, das ist falsch . Das Konvertieren eines Base64-Strings in sein binäres Äquivalent macht ihn nicht zu einem Image. (Danke @elliotwesoff für den Hinweis!) Und warum erwähnen Sie Binärdaten ? Diese Frage erwähnt in keiner Weise binär oder sogar, wie man es konvertiert.
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
Während dieser Code das Problem des OP lösen kann, ist es am besten, eine Erklärung beizufügen, wie Ihr Code das Problem des OP behebt. Auf diese Weise können zukünftige Besucher aus Ihrem Beitrag lernen und ihn auf ihren eigenen Code anwenden. SO ist kein Codierungsdienst, sondern eine Ressource für Wissen. Es ist auch wahrscheinlicher, dass qualitativ hochwertige, vollständige Antworten positiv bewertet werden. Diese Funktionen sowie die Anforderung, dass alle Beiträge in sich geschlossen sind, sind einige der Stärken von SO als Plattform, die es von Foren unterscheidet. Sie können bearbeiten, um zusätzliche Informationen hinzuzufügen und / oder Ihre Erklärungen durch Quelldokumentation zu ergänzen.
ysf
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.