convertir una cadena base 64 en una imagen y guardarla

132

Aquí está mi código:

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 declaración superior de imageUrl está tomando una cadena de imagen Base64, y quiero convertirla en una imagen. Creo que mi conjunto de códigos solo funciona para imágenes como "www.mysite.com/test.jpg", no para una cadena Base64. Alguien tiene algunas sugerencias? ¡Gracias!

anthonypliu
fuente

Respuestas:

218

Aquí hay un ejemplo, puede modificar el método para aceptar un parámetro de cadena. Luego simplemente guarde el objeto de imagen con 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 posible obtener una excepción A generic error occurred in GDI+.cuando los bytes representan un mapa de bits. Si esto sucede, guarde la imagen antes de desechar el flujo de memoria (mientras aún está dentro de la instrucción de uso).

CRice
fuente
Este método me da un rectángulo negro, ¿tienes alguna idea?
katmanco
54
Sí, este es un píxel negro: R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw ==
CRice
66
@katmanco Creo que el píxel negro se proporcionó como ejemplo. Intente reemplazar la cadena base64 de ejemplo con su propia cadena base64
kallotec 9/15
2
Es posible que deba agregar una referencia a la DLL de System.Drawing
Philip Rego
1
@Bibin, ¿intentaste guardar la imagen dentro de la declaración de uso?
CRice
83

Puede guardar Base64 directamente en el archivo:

string filePath = "MyImage.jpg";
File.WriteAllBytes(filePath, Convert.FromBase64String(base64imageString));
INT_24h
fuente
Esta es una excelente solución en mi caso donde estaba usando mono en Linux y experimentaba un comportamiento extraño con gdi + en Image.Save. Esta solución omite completamente Image / Gdi + (ver stackoverflow.com/questions/35783690/… )
Jeff Albrecht
1
Intenté esto y la solución de @ CRice (usando Image.Save()). Ambos funcionan, pero por alguna razón, esta versión hace que el tamaño de mi archivo sea un 30% más pequeño sin cambios perceptibles en la calidad de la imagen
Brad Mathews
31

Aquí es con lo que terminé yendo.

    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
fuente
77
Esto me dio un error A generic error occurred in GDI+descrito aquí . Mover el image.Saveinterior del bloque de uso lo arregló para mí.
JumpingJezza
11

Sugeriría a través de 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
fuente
2
¿Cuál es la diferencia entre convertir a través de mapa de bits o sin mapa de bits? thx
Amine Da.
6

En mi caso solo funciona con dos líneas de código. Pruebe el siguiente código C #:

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

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

Eso es. Vota amablemente si realmente encuentras que esta solución funciona para ti. Gracias por adelantado.

Milan Sheth
fuente
1
Es una copia de mi respuesta (ver abajo stackoverflow.com/a/35160048/4190593 ) :)
INT_24h
-1 porque dirPathtiene que tener un @signo antes de la cadena i..e. @"C:\myfolder\"o tienes que escapar de las barras invertidas en la cadena, es decir"C:\\myfolder\\"
Marcus Parsons
debe proporcionar referencia a esa otra respuesta en lugar de tomar todo el crédito ...
Arshi
6

Aquí hay un código de trabajo para convertir una imagen de una cadena base64 a un Imageobjeto y almacenarla en una carpeta con un nombre de archivo único:

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
fuente
5

En un escenario similar, lo que funcionó para mí fue lo siguiente:

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

ImageTagId es la ID de la etiqueta de imagen ASP.

abhishek
fuente
5

Si tiene una cadena de datos binarios codificada en Base64, debería poder hacer lo siguiente:

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

Debería poder escribir la matriz resultante en un archivo.

afranz409
fuente
Esto no funciona Simplemente convierte la cadena base64 a su equivalente binario. Escribir eso en un archivo con una extensión de imagen no lo convierte en una imagen.
elliotwesoff
1
¿No? Lo siento, esto es incorrecto . La conversión de una cadena Base64 a su equivalente binario no la convierte en una imagen. (¡Gracias @elliotwesoff por señalar eso!) ¿Y por qué mencionas datos binarios ? Esta pregunta de ninguna manera menciona binario , o incluso cómo convertirlo.
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
fuente
2
Si bien este código puede resolver el problema del OP, es mejor incluir una explicación sobre cómo su código aborda el problema del OP. De esta forma, los futuros visitantes pueden aprender de su publicación y aplicarla a su propio código. SO no es un servicio de codificación, sino un recurso para el conocimiento. Además, es más probable que se voten las respuestas completas de alta calidad. Estas características, junto con el requisito de que todas las publicaciones sean independientes, son algunos de los puntos fuertes de SO como plataforma, que lo diferencia de los foros. Puede editar para agregar información adicional y / o complementar sus explicaciones con la documentación de origen.
ysf