convertendo uma string de base 64 em uma imagem e salvando-a

132

Aqui está o meu 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();
            }
        }
}

A declaração imageUrl superior está recebendo uma string de imagem Base64 e quero convertê-la em uma imagem. Acho que meu conjunto de códigos funciona apenas para imagens como "www.mysite.com/test.jpg" e não para uma string Base64. Alguém tem alguma sugestão? Obrigado!

anthonypliu
fonte

Respostas:

218

Aqui está um exemplo, você pode modificar o método para aceitar um parâmetro de string. Em seguida, salve o objeto de imagem com 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;
}

É possível obter uma exceção A generic error occurred in GDI+.quando os bytes representam um bitmap. Se isso estiver acontecendo, salve a imagem antes de descartar o fluxo de memória (ainda dentro da instrução using).

CRice
fonte
Esse método me dá um retângulo preto, você tem alguma ideia?
Katmanco #
54
Sim, este é um pixel preto: R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAALAAAAAABAAEAAAICTAEAOw ==
CRice
6
@ Katmanco Eu acho que o pixel preto foi fornecido como exemplo. Tente substituir o exemplo seqüência de base64 com sua própria seqüência de base64
kallotec
2
Talvez você precise adicionar uma referência à DLL System.Drawing
Philip Rego
1
@Bibin você tentou salvar a imagem dentro da instrução using?
CRice 26/09/19
83

Você pode salvar o Base64 diretamente no arquivo:

string filePath = "MyImage.jpg";
File.WriteAllBytes(filePath, Convert.FromBase64String(base64imageString));
INT_24h
fonte
Esta é uma excelente solução no meu caso em que eu estava usando mono no Linux e tive um comportamento estranho com o gdi + no Image.Save. Esta solução ignora completamente o Image / Gdi + (consulte stackoverflow.com/questions/35783690/… )
Jeff Albrecht
1
Eu tentei isso e a solução do @ CRice (usando Image.Save()). Ambos funcionam, mas, por algum motivo, esta versão torna o tamanho do meu arquivo 30% menor, sem alterações perceptíveis na qualidade da imagem
315 Brad Mathews
31

Aqui está o que eu acabei indo.

    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
fonte
7
Isso me deu um erro A generic error occurred in GDI+descrito aqui . Mover o image.Saveinterior do bloco usando o corrigiu para mim.
precisa saber é o seguinte
11

Eu sugeriria 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");
        }
    }
}
Nishant Kumar
fonte
2
qual é a diferença entre converter via bitmap ou sem bitmap? thx
Amina Da.
6

No meu caso, funciona apenas com duas linhas de código. Teste o código C # abaixo:

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

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

É isso aí. Por favor, vote se você realmente achar que esta solução funciona para você. Desde já, obrigado.

Milan Sheth
fonte
1
É cópia da minha resposta (veja abaixo stackoverflow.com/a/35160048/4190593 ) :)
INT_24h 06/06/06
-1 porque dirPathprecisa ter um @sinal antes da string i..e. @"C:\myfolder\"ou você tem que escapar das barras invertidas na string ie"C:\\myfolder\\"
Marcus Parsons
você deve fornecer uma referência para que outra resposta em vez de tomar crédito inteira ....
Arshi
6

Aqui está o código de trabalho para converter uma imagem de uma string base64 em um Imageobjeto e armazená-la em uma pasta com um nome de arquivo exclusivo:

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

Em um cenário semelhante, o que funcionou para mim foi o seguinte:

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

ImageTagId é o ID da marca de imagem ASP.

abhishek
fonte
5

Se você tiver uma sequência de dados binários codificados em Base64, poderá fazer o seguinte:

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

Você deve conseguir gravar a matriz resultante em um arquivo.

afranz409
fonte
Isso não funciona. Ele apenas converte a string base64 em seu equivalente binário. Escrever isso em um arquivo com extensão de imagem não o torna uma imagem.
Elliotwesoff 28/08/19
1
Não? Sinto muito, isso está incorreto . Converter uma cadeia Base64 em seu equivalente binário não a torna uma imagem. (Obrigado @elliotwesoff por apontar isso!) E, por que você está mencionando dados binários ? Esta questão de forma alguma menciona binário , ou mesmo como convertê-lo.
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
fonte
2
Embora esse código possa resolver o problema do OP, é melhor incluir uma explicação sobre como o seu código soluciona o problema do OP. Dessa forma, futuros visitantes podem aprender com sua postagem e aplicá-la ao próprio código. O SO não é um serviço de codificação, mas um recurso para o conhecimento. Além disso, respostas completas de alta qualidade têm mais probabilidade de serem votadas. Esses recursos, juntamente com o requisito de que todas as postagens sejam independentes, são alguns dos pontos fortes do SO como plataforma, que o diferencia dos fóruns. Você pode editar para adicionar informações adicionais e / ou complementar suas explicações com a documentação de origem.
ysf 27/06