将图像异步转换为 Base64 的 C# 简单应用程序
Posted
技术标签:
【中文标题】将图像异步转换为 Base64 的 C# 简单应用程序【英文标题】:C# Simple app to convert images into Base64 asynchronously 【发布时间】:2022-01-19 09:24:53 【问题描述】:我正在尝试制作一个简单的 winforms 应用程序来将图像转换为 Base64。调试时,我注意到当我单击转换为 base64 的按钮时 ui 冻结,因此我开始更改代码以异步调用该方法。 (碰巧我从来没有使用过 Async 方法,所以我有点不知道自己在做什么)
我的 form1.cs 代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ImageToBase64
public partial class main : Form
public main()
InitializeComponent();
Util Util = new Util();
private void button1_Click(object sender, EventArgs e)
imageDialog.FileName = "";
imageDialog.Title = "Selecionar Imagem";
imageDialog.Filter = "JPEG|*.JPG|PNG|*.png";
imageDialog.ShowDialog();
imagePathText.Text = imageDialog.FileName;
private void button2_Click(object sender, EventArgs e)
imageCode.Text = "";
Task<string> base64Code = Task.Run(() => Util.ToBase64(imageDialog.FileName));
imageCode.Text = base64Code.Result;
我的 Util.cs 代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ImageToBase64
class Util
public async Task<string> ToBase64(string img)
string path = img;
using (System.Drawing.Image image = System.Drawing.Image.FromFile(path))
using (MemoryStream m = new MemoryStream())
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
string base64String = null;
base64String = Convert.ToBase64String(imageBytes);
return base64String;
即使在进行了这些更改后,UI 仍然冻结,我可以做些什么来解决这个问题?
【问题讨论】:
base64Code.Result;
- 您正在以同步的方式访问任务的结果,阻止一切。你必须让你的button2_Click
异步。
请改用await Task.Run(() => Util.ToBase64(...)
。这个方法也很可疑——为什么要使用Image
?这将编码原始 RGB 字节而不是文件数据。您可以使用var imageBytes=await File.ReadAllBytesAsync(path); var base64=Convert.ToBase64String(imageBytes);
转换文件数据
ToBase64
没有做任何有用的事情 - 除了由于有损压缩而降低质量之外,它产生的字节与存储在文件中的字节相同。
【参考方案1】:
首先,代码阻塞了任务。其次,方法ToBase64
最终生成和编码原始 字节,假设没有由于有损压缩而丢失。 image.Save(m, image.RawFormat);
以原始格式保存图像数据,因此最多只能生成相同的数据。
代码可以简化为:
private async void button2_Click(object sender, EventArgs e)
//Only needed to provide a visual cue
imageCode.Text="";
var bytes=await File.ReadAllBytes(imageDialog.FileName);
imageCode.Text = await Task.Run(()=>Convert.ToBase64String(bytes));
如果您想在编码之前将图像转换为不同的格式,或者如果您想对原始 RGB 值进行编码,则使用 Image
会很有意义
【讨论】:
【参考方案2】:原因是这样的
imageCode.Text = base64Code.Result;
.Result
将阻塞直到可以生成字符串,这可能不是您想要的。
您应该改用 async/await:
imageCode.Text = await base64Code;
请注意,这需要将方法标记为异步。而且您可能还想捕获任何异常,否则它们可能会丢失。
我还建议使用一些分析工具,因为这些工具通常可以告诉您代码的哪些部分阻塞了 UI。
【讨论】:
以上是关于将图像异步转换为 Base64 的 C# 简单应用程序的主要内容,如果未能解决你的问题,请参考以下文章
我想将图像数据(Texture2D)转换为 Base64 字符串并存储在 Unity3D(C#)中的 JSON 文件中