为什么有第二版
首先感谢 jenlynn 同学的留言“DATA URL两种生成方式,C#和HTML5 两者同一张生成的base64编码貌似不一样,能有什么方法让他们达成一致吗”。
其次,在研究这个问题时发现了Bug和异常。
Bug:图片编码判断问题,不管什么扩展名的都默认使用了PNG编码。
异常:检测到 ContextSwitchDeadlock
界面预览

针对相关问题的改进方法
图片编码判断问题
之前主要是忘记了获取的扩展名前面是带点.的
相关代码:
string ext = Path.GetExtension(path).ToLower();
//根据文件的扩展名确定使用的编码格式
//注意扩展名是带点的!
switch (ext)
{
case ".gif":
fmt = System.Drawing.Imaging.ImageFormat.Gif;
break;
case ".jpg":
case ".jpeg":
fmt = System.Drawing.Imaging.ImageFormat.Jpeg;
break;
case ".ico":
fmt = System.Drawing.Imaging.ImageFormat.Icon;
break;
default:
ext = "png";
break;
}检测到 ContextSwitchDeadlock
解决方法说明
StackOverflow提到使用BackgroundWorker,我这里使用线程;但是经过测试发现:由于TextBox显示大文本时的性能问题,线程与TextBox交互时,如果用户不操作的话,窗口不会死;一旦有任何操作,窗口就是不响应!
所以只能改变解决方案,使用折中的办法,不让TextBox显示全部的DataUrl字符串,只显示其中的一部分;使用一个变量“”来保存完整的DataUrl字符串,点击复制按钮时将其Copy到Windows剪贴板中。
相关代码
////// 用于保存完整的DataUrl /// private string fullDataUrl = string.Empty;
使用线程
//创建线程来生成DataUrl
System.Threading.Thread thd = new System.Threading.Thread(new ParameterizedThreadStart(buildDataUrl));
thd.Start(textBox_saveDir.Text);使用委托
////// TextBox委托,用于实现线程中访问窗体、组件等的线程安全性 /// /// public delegate void textbox_delegate(string msg); ////// TextBox委托实现,用于实现线程中访问窗体、组件等的线程安全性 /// /// public void textboxset(string msg) { if (textBox1 == null) return; if (textBox1.InvokeRequired) { textbox_delegate dt = new textbox_delegate(textboxset); textBox1.Invoke(dt, new object[] { msg }); } else { int strLen = msg.Length; int step = 100; while (strLen > step) { textBox1.AppendText(msg.Substring(msg.Length - strLen, step)); strLen -= step; } textBox1.AppendText(msg.Substring(msg.Length - strLen, strLen)); } }
优化Base64编码
//计算Base64编码的字符串后部分有多少可以省略的字符
int strLen = str.Length;
string dyzf = str.Substring(strLen - 1, 1);
while ((dyzf == "A" || dyzf == "=") && strLen > 0)
{
strLen -= 1;
dyzf = str.Substring(strLen - 1, 1);
} //组合完整的Data Url
fullDataUrl = "@@##@@";
//这里定义TextBox最多只显示20000个字符,多余的裁掉不显示了,不然性能太差。
int showLen = 20000; if (showLen > fullDataUrl.Length)
{
showLen = fullDataUrl.Length;
}
textboxset(fullDataUrl.Substring(0, showLen));////// 将完整的Data Url复制到Windows剪贴板中。 /// /// /// private void button_copy_Click(object sender, EventArgs e) { Clipboard.SetText(fullDataUrl); }
////// 清空文本框 /// /// /// private void button_clear_Click(object sender, EventArgs e) { textBox1.Clear(); fullDataUrl = string.Empty; }










