การแปลงสตริงฐาน 64 เป็นรูปภาพและบันทึก


132

นี่คือรหัสของฉัน:

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

การประกาศ imageUrl ด้านบนกำลังถ่ายในสตริงอิมเมจ Base64 และฉันต้องการแปลงให้เป็นรูปภาพ ฉันคิดว่าชุดโค้ดของฉันใช้ได้กับรูปภาพเช่น "www.mysite.com/test.jpg" ไม่ใช่สำหรับสตริง Base64 ใครมีคำแนะนำบ้าง? ขอบคุณ!

คำตอบ:


218

นี่คือตัวอย่างคุณสามารถแก้ไขวิธีการยอมรับพารามิเตอร์สตริง จากนั้นเพียงแค่บันทึกภาพวัตถุที่มี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;
}

เป็นไปได้ที่จะได้รับข้อยกเว้นA generic error occurred in GDI+.เมื่อไบต์แทนบิตแมป หากสิ่งนี้เกิดขึ้นให้บันทึกภาพก่อนที่จะทิ้งสตรีมหน่วยความจำ (ในขณะที่ยังอยู่ในข้อความสั่งการใช้งาน)


วิธีนี้ให้สี่เหลี่ยมสีดำกับฉันคุณมีความคิดไหม?
katmanco

54
ใช่นี่เป็นพิกเซลสีดำ: R0lGODlhAQABAIAAAAAAAAAAACHACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw ==
CRice

6
@katmanco ฉันคิดว่าพิกเซลสีดำเป็นตัวอย่าง ลองแทนที่สตริง base64 ตัวอย่างด้วยสตริง base64 ของคุณเอง
kallotec

2
คุณอาจต้องเพิ่มการอ้างอิงไปยัง System.Drawing DLL
Philip Rego

1
@Bibin คุณลองบันทึกภาพไว้ในข้อความสั่งการใช้งานหรือไม่?
CRice

83

คุณสามารถบันทึก Base64 ลงในไฟล์ได้โดยตรง:

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

นี่เป็นทางออกที่ยอดเยี่ยมในกรณีของฉันที่ฉันใช้ mono บน Linux และพบกับพฤติกรรมแปลก ๆ กับ gdi + ใน Image.Save วิธีการแก้ปัญหานี้ข้ามรูปภาพ / Gdi + (ดูstackoverflow.com/questions/35783690/… )
Jeff Albrecht

1
ฉันลองทั้งโซลูชันนี้และของ @ CRice (โดยใช้Image.Save()) ทำงานได้ทั้งสองอย่าง แต่ด้วยเหตุผลบางอย่างรุ่นนี้ทำให้ขนาดไฟล์ของฉันเล็กลง 30% โดยไม่มีการเปลี่ยนแปลงคุณภาพของภาพที่เห็นได้ชัดเจน
Brad Mathews

31

นี่คือสิ่งที่ฉันจะไปด้วย

    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
นี้ให้ฉันข้อผิดพลาดA generic error occurred in GDI+ที่อธิบายไว้ที่นี่ การเคลื่อนย้ายimage.Saveด้านในโดยใช้บล็อคได้รับการแก้ไขสำหรับฉัน
JumpingJezza

11

ฉันจะแนะนำผ่านบิตแมป:

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
อะไรคือความแตกต่างระหว่างการแปลงผ่านบิตแมปหรือไม่มีบิตแมป ขอบคุณ
Amine Da

6

ในกรณีของฉันมันใช้ได้กับโค้ดสองบรรทัดเท่านั้น ทดสอบรหัส C # ด้านล่าง:

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

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

แค่นั้นแหละ. กรุณาลงคะแนนหากคุณพบว่าวิธีนี้ใช้ได้ผลสำหรับคุณ ขอบคุณล่วงหน้า.


1
นี่เป็นสำเนาของคำตอบของฉัน (ดูด้านล่างstackoverflow.com/a/35160048/4190593 ) :)
INT_24h

-1 เนื่องจากdirPathต้องมี@เครื่องหมายหน้าสตริง i..e @"C:\myfolder\"หรือคุณต้องหลบหลีกแบ็กสแลชในสตริงนั่นคือ"C:\\myfolder\\"
Marcus Parsons

คุณควรให้การอ้างอิงกับคำตอบอื่น ๆ แทนการใช้เครดิตทั้งหมด ....
Arshi

6

นี่คือโค้ดที่ใช้งานได้สำหรับการแปลงรูปภาพจากสตริง base64 ไปเป็นImageวัตถุและเก็บไว้ในโฟลเดอร์ที่มีชื่อไฟล์ที่ไม่ซ้ำกัน:

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

ในสถานการณ์ที่คล้ายกันสิ่งที่ใช้ได้ผลสำหรับฉันคือ:

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

ImageTagId คือ ID ของแท็กรูปภาพ ASP


5

หากคุณมีสตริงของข้อมูลไบนารีซึ่งเข้ารหัส Base64 คุณควรทำสิ่งต่อไปนี้:

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

คุณควรจะสามารถเขียนอาร์เรย์ผลลัพธ์ลงในไฟล์


มันใช้งานไม่ได้ มันเพียงแปลงสตริง base64 ให้เทียบเท่าไบนารี การเขียนลงในไฟล์ที่มีนามสกุลภาพนั้นไม่ได้ทำให้เป็นภาพ
elliotwesoff

1
ไม่มี? ฉันขอโทษนี้เป็นที่ไม่ถูกต้อง การแปลงสตริง Base64 เป็นค่าเทียบเท่าไบนารีไม่ได้ทำให้เป็นอิมเมจ (ขอบคุณ @elliotwesoff สำหรับการชี้ว่า!) และทำไมคุณถึงพูดถึงข้อมูลไบนารี ? คำถามนี้ไม่ได้พูดถึงไบนารีหรือแม้กระทั่งวิธีการแปลง
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
ในขณะที่รหัสนี้อาจแก้ไขปัญหาของ OP ได้วิธีที่ดีที่สุดคือรวมคำอธิบายว่ารหัสของคุณแก้ไขปัญหาของ OP ได้อย่างไร ด้วยวิธีนี้ผู้เข้าชมในอนาคตสามารถเรียนรู้จากโพสต์ของคุณและนำไปใช้กับรหัสของตนเอง ดังนั้นไม่ใช่บริการการเข้ารหัส แต่เป็นแหล่งความรู้ นอกจากนี้คุณภาพสูงและคำตอบที่สมบูรณ์มีแนวโน้มที่จะถูกถอนออก คุณสมบัติเหล่านี้พร้อมกับข้อกำหนดที่โพสต์ทั้งหมดมีอยู่ในตัวเองเป็นจุดแข็งของ SO ในฐานะแพลตฟอร์มซึ่งแตกต่างจากฟอรัม คุณสามารถแก้ไขเพื่อเพิ่มข้อมูลเพิ่มเติม & / หรือเสริมคำอธิบายของคุณด้วยเอกสารต้นฉบับ
ysf
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.