conversion d'une chaîne de base 64 en image et enregistrement de celle-ci


132

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

La déclinaison imageUrl supérieure prend une chaîne d'image Base64, et je souhaite la convertir en image. Je pense que mon ensemble de code ne fonctionne que pour des images comme "www.monsite.com/test.jpg" et non pour une chaîne Base64. Quelqu'un a des suggestions? Merci!

Réponses:


219

Voici un exemple, vous pouvez modifier la méthode pour accepter un paramètre de chaîne. Ensuite, enregistrez simplement l'objet image avec 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;
}

Il est possible d'obtenir une exception A generic error occurred in GDI+.lorsque les octets représentent un bitmap. Si cela se produit, enregistrez l'image avant de supprimer le flux de mémoire (tout en restant dans l'instruction using).


Cette méthode me donne un rectangle noir, avez-vous une idée?
katmanco

54
Oui, c'est un pixel noir: R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw ==
CRice

6
@katmanco Je pense que le pixel noir a été fourni à titre d'exemple. Essayez de remplacer l'exemple de chaîne base64 par votre propre chaîne base64
kallotec

2
Vous devrez peut-être ajouter une référence à la DLL System.Drawing
Philip Rego

1
@Bibin avez-vous essayé d'enregistrer l'image dans l'instruction using?
CRice

83

Vous pouvez enregistrer Base64 directement dans le fichier:

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

C'est une excellente solution dans mon cas où j'utilisais mono sur Linux et que j'avais rencontré un comportement étrange avec gdi + dans Image.Save. Cette solution contourne complètement Image / Gdi + (Voir stackoverflow.com/questions/35783690/… )
Jeff Albrecht

1
J'ai essayé à la fois ceci et la solution de @ CRice (en utilisant Image.Save()). Les deux fonctionnent, mais pour une raison quelconque, cette version réduit la taille de mon fichier de 30% sans changement perceptible de la qualité d'image
Brad Mathews

31

Voici ce que j'ai fini par faire.

    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
Cela m'a donné une erreur A generic error occurred in GDI+décrite ici . Déplacer l' image.Saveintérieur du bloc using l'a corrigé pour moi.
JumpingJezza

11

Je suggérerais via 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
quelle est la différence entre la conversion via bitmap ou sans bitmap? thx
Amine Da.

6

Dans mon cas, cela ne fonctionne qu'avec deux lignes de code. Testez le code C # ci-dessous:

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

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

C'est tout. Veuillez voter si vous trouvez vraiment que cette solution fonctionne pour vous. Merci d'avance.


1
C'est une copie de ma réponse (voir ci-dessous stackoverflow.com/a/35160048/4190593 ) :)
INT_24h

-1 car dirPathdoit avoir un @signe avant la chaîne i..e. @"C:\myfolder\"ou vous devez échapper aux contre-obliques dans la chaîne ie"C:\\myfolder\\"
Marcus Parsons

vous devriez fournir une référence à cette autre réponse au lieu de vous en attribuer tout le mérite ....
Arshi

6

Voici un code de travail pour convertir une image d'une chaîne base64 en Imageobjet et la stocker dans un dossier avec un nom de fichier unique:

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

Dans un scénario similaire, ce qui a fonctionné pour moi était le suivant:

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

ImageTagId est l'ID de la balise d'image ASP.


5

Si vous avez une chaîne de données binaires encodée en Base64, vous devriez pouvoir effectuer les opérations suivantes:

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

Vous devriez pouvoir écrire le tableau résultant dans un fichier.


Cela ne marche pas. Il convertit simplement la chaîne base64 en son équivalent binaire. L'écrire dans un fichier avec une extension d'image n'en fait pas une image.
elliotwesoff

1
Non? Je suis désolé, c'est incorrect . La conversion d'une chaîne Base64 en son équivalent binaire n'en fait pas une image. (Merci @elliotwesoff pour l'avoir signalé!) Et pourquoi mentionnez-vous des données binaires ? Cette question ne mentionne en aucun cas le binaire , ni même comment le convertir.
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
Bien que ce code puisse résoudre le problème du PO, il est préférable d'inclure une explication sur la façon dont votre code résout le problème du PO. De cette manière, les futurs visiteurs peuvent apprendre de votre publication et l'appliquer à leur propre code. SO n'est pas un service de codage, mais une ressource de connaissances. De plus, les réponses complètes et de haute qualité sont plus susceptibles d'être votées. Ces fonctionnalités, ainsi que l'exigence que tous les messages soient autonomes, sont quelques-unes des forces de SO en tant que plate-forme, qui le différencie des forums. Vous pouvez modifier pour ajouter des informations supplémentaires et / ou pour compléter vos explications avec la documentation source.
ysf le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.