64 temel dizeyi bir görüntüye dönüştürmek ve kaydetmek


132

İşte kodum:

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

En üstteki imageUrl bildirimi bir Base64 görüntü dizesi alıyor ve bunu bir görüntüye dönüştürmek istiyorum. Kod setimin yalnızca "www.mysite.com/test.jpg" gibi görseller için çalıştığını düşünüyorum, Base64 dizesi için değil. Herhangi bir öneriniz var mı? Teşekkürler!

Yanıtlar:


219

İşte bir örnek, bir dize parametresini kabul etmek için yöntemi değiştirebilirsiniz. Ardından görüntü nesnesini image.Save (...) ile kaydedin .

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

A generic error occurred in GDI+.Baytlar bir bitmap'i temsil ettiğinde bir istisna elde etmek mümkündür . Bu oluyorsa, bellek akışını atmadan önce görüntüyü kaydedin (hala using deyiminin içindeyken).


Bu yöntem bana siyah dikdörtgen veriyor, herhangi bir fikrin var mı?
katmanco

54
Evet, bu siyah bir piksel: R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAAABAAEAAAICTAEAOw ==
CRice

6
@katmanco Siyah pikselin örnek olarak verildiğini düşünüyorum. Örnek base64 dizesini kendi base64
dizenizle

2
System.Drawing DLL'ye bir referans eklemeniz gerekebilir
Philip Rego

1
@Bibin, using ifadesinin içindeki görüntüyü kaydetmeyi denediniz mi?
CRice

83

Base64'ü doğrudan dosyaya kaydedebilirsiniz:

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

Bu, Linux'ta mono kullandığım ve Image.Save'de gdi + ile bazı garip davranışlar yaşadığım durumum için mükemmel bir çözüm. Bu çözüm Image / Gdi + 'yı tamamen atlıyor (Bkz. Stackoverflow.com/questions/35783690/… )
Jeff Albrecht

1
Hem bunu hem de @ CRice'nin çözümünü (kullanarak Image.Save()) denedim . Her ikisi de işe yarıyor, ancak bazı nedenlerden dolayı bu sürüm dosya boyutumu% 30 daha küçük yapıyor, görüntü kalitesinde fark edilebilir bir değişiklik yok
Brad Mathews

31

İşte sonunda neyle sonuçlandığım.

    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
Bu bana buradaA generic error occurred in GDI+ açıklanan bir hata verdi . İçeriyi kullanarak bloğu hareket ettirmek benim için sabitledi. image.Save
JumpingJezza

11

Bitmap aracılığıyla şunları öneririm:

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
bitmap aracılığıyla veya bitmap olmadan dönüştürme arasındaki fark nedir? thx
Amin Da.

6

Benim durumumda sadece iki satır kodla çalışıyor. Aşağıdaki C # kodunu test edin:

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

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

Bu kadar. Bu çözümün sizin için gerçekten işe yaradığını düşünüyorsanız lütfen oy verin. Şimdiden teşekkürler.


1
Cevabımın bir kopyası (aşağıdaki stackoverflow.com/a/35160048/4190593'e bakın ) :)
INT_24h

-1 çünkü i..e dizesinden önce dirPathbir @işarete sahip olmak zorundadır. @"C:\myfolder\"veya dizedeki ters eğik çizgilerden kaçmanız gerekir, yani"C:\\myfolder\\"
Marcus Parsons

bütün
övgü

6

Bir görüntüyü base64 dizesinden bir Imagenesneye dönüştürmek ve onu benzersiz dosya adına sahip bir klasörde depolamak için çalışma kodu :

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

Benzer bir senaryoda benim için işe yarayan şey şuydu:

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

ImageTagId ASP resim etiketinin kimliğidir.


5

Base64 kodlu bir ikili veri dizeniz varsa, aşağıdakileri yapabilmelisiniz:

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

Elde edilen diziyi bir dosyaya yazabilmelisiniz.


Bu çalışmıyor. Sadece base64 dizesini ikili eşdeğerine dönüştürür. Bunu bir resim uzantılı bir dosyaya yazmak onu resim yapmaz.
elliotwesoff

1
Hayır? Bunun olduğunu üzgünüm yanlış . Bir Base64 dizesini ikili eşdeğerine dönüştürmek , onu bir görüntü yapmaz. (Bunu belirttiğiniz için teşekkürler @elliotwesoff!) Ve neden ikili veriden bahsediyorsunuz ? Hiçbir şekilde bu soru bahseder ikili biçimine dönüştürebilirsiniz bile ya.
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
Bu kod OP'nin sorununu çözebilirken, kodunuzun OP'nin sorununu nasıl ele aldığına dair bir açıklama eklemek en iyisidir. Bu şekilde, gelecekteki ziyaretçiler gönderinizden öğrenebilir ve kendi kodlarına uygulayabilir. SO bir kodlama hizmeti değil, bilgi için bir kaynaktır. Ayrıca, yüksek kaliteli, eksiksiz yanıtların olumlu oy kullanma olasılığı daha yüksektir. Bu özellikler, tüm gönderilerin bağımsız olması gerekliliğinin yanı sıra, onu forumlardan ayıran bir platform olarak SO'nun güçlü yönlerinden bazılarıdır. Ek bilgi eklemek ve / veya açıklamalarınızı kaynak belgelerle desteklemek için düzenleme yapabilirsiniz.
ysf
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.