【问题标题】:converting a base 64 string to an image and saving it将 base 64 字符串转换为图像并保存
【发布时间】:2011-07-20 23:41:30
【问题描述】:

这是我的代码:

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 字符串。有人有什么建议吗?谢谢!

【问题讨论】:

  • 尝试使用:byte[] bytesContent = Convert.FromBase64String(Str64File);

标签: c# asp.net image-processing base64


【解决方案1】:

这里是一个例子,你可以修改方法来接受一个字符串参数。然后只需使用 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+.。如果发生这种情况,请在释放内存流之前保存图像(同时仍在 using 语句中)。

【讨论】:

  • 这个方法给我黑色矩形,你知道吗?
  • 是的,这是一个黑色像素:R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==
  • @katmanco 我认为黑色像素是作为示例提供的。尝试用您自己的 base64 字符串替换示例 base64 字符串
  • 您可能需要添加对 System.Drawing DLL 的引用
  • @Bibin 您是否尝试将图像保存在 using 语句中?
【解决方案2】:

您可以将Base64直接保存到文件中:

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

【讨论】:

  • 在我在 Linux 上使用 mono 并且在 Image.Save 中使用 gdi+ 时遇到了一些奇怪的行为时,这是一个很好的解决方案。此解决方案完全绕过 Image / Gdi+(参见stackoverflow.com/questions/35783690/…
  • 我尝试了这个和@CRice 的解决方案(使用Image.Save())。两者都有效,但由于某种原因,这个版本使我的文件大小减小了 30%,而图像质量没有明显变化
【解决方案3】:

这是我最终的结果。

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

【讨论】:

  • 这给了我一个错误A generic error occurred in GDI+ 描述here。在 using 块中移动 image.Save 为我修复了它。
【解决方案4】:

我会建议通过位图:

public void SaveImage(string base64)
{
    using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(base64)))
    {
        using (Bitmap bm2 = new Bitmap(ms))
        {
            bm2.Save("SavingPath" + "ImageName.jpg");
        }
    }
}

【讨论】:

  • 通过位图转换和不用位图有什么区别?谢谢
【解决方案5】:

就我而言,它仅适用于两行代码。测试以下 C# 代码:

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

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

就是这样。如果您真的发现此解决方案适合您,请投票。提前致谢。

【讨论】:

  • 这是我的答案的副本(见下文stackoverflow.com/a/35160048/4190593):)
  • -1 因为dirPath 必须在字符串之前有一个@ 符号,即@"C:\myfolder\" 或者您必须转义字符串中的反斜杠,即"C:\\myfolder\\"
  • 您应该提供对其他答案的参考,而不是全部功劳......
【解决方案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();
    }
}

【讨论】:

    【解决方案7】:

    在类似的情况下,对我有用的是:

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

    ImageTagId 是 ASP 图片标签的 ID。

    【讨论】:

      【解决方案8】:

      如果您有一串经过 Base64 编码的二进制数据,您应该能够执行以下操作:

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

      您应该能够将结果数组写入文件。

      【讨论】:

      • 这不起作用。它只是将 base64 字符串转换为其二进制等价物。将其写入具有图像扩展名的文件不会使其成为图像。
      • 否?对不起,这是不正确的。将 Base64 字符串转换为其 二进制等效项 不会使其成为图像。 (感谢@elliotwesoff 指出这一点!)而且,为什么你提到二进制数据?这个问题没有提到binary,甚至没有提到如何转换它。
      【解决方案9】:
      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;
          }
      
      }
      

      【讨论】:

      • 虽然此代码可以解决 OP 的问题,但最好包含关于您的代码如何解决 OP 问题的说明。这样,未来的访问者可以从您的帖子中学习,并将其应用到他们自己的代码中。 SO 不是编码服务,而是知识资源。此外,高质量、完整的答案更有可能得到支持。这些功能,以及所有帖子都是独立的要求,是 SO 作为一个平台的一些优势,使其与论坛区分开来。您可以编辑以添加其他信息和/或使用源文档补充您的解释。
      【解决方案10】:

      使用 MemoryStream 不是一个好主意,它违反了 MSDN 中针对 Image.FromStream() 的规范,其中提到

      您必须在图像的生命周期内保持流打开。

      更好的解决方案是使用ImageConverter,例如:

      public Image ConvertBase64ToImage(string base64)
          => (Bitmap)new ImageConverter().ConvertFrom(Convert.FromBase64String(base64));
      
      

      【讨论】:

      • 没错。当您想使用图像而不保存在本地存储中时,这是一个很好的解决方案
      猜你喜欢
      • 2017-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-09
      • 1970-01-01
      • 1970-01-01
      • 2018-01-22
      相关资源
      最近更新 更多