首先感谢 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剪贴板中。
相关代码
/// <summary> /// 用于保存完整的dataurl /// </summary> private string fulldataurl = string.empty;
使用线程
//创建线程来生成dataurl system.threading.thread thd = new system.threading.thread(new parameterizedthreadstart(builddataurl)); thd.start(textbox_savedir.text);
使用委托
/// <summary> /// textbox委托,用于实现线程中访问窗体、组件等的线程安全性 /// </summary> /// <param name="msg"></param> public delegate void textbox_delegate(string msg); /// <summary> /// textbox委托实现,用于实现线程中访问窗体、组件等的线程安全性 /// </summary> /// <param name="msg"></param> 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 = "<img src=\"data:image/" + ext + ";base64," + str.substring(0, strlen) + "\" width=\"" + img.width + "\" height=\"" + img.height + "\" />"; //这里定义textbox最多只显示20000个字符,多余的裁掉不显示了,不然性能太差。 int showlen = 20000; if (showlen > fulldataurl.length) { showlen = fulldataurl.length; } textboxset(fulldataurl.substring(0, showlen));
/// <summary> /// 将完整的data url复制到windows剪贴板中。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button_copy_click(object sender, eventargs e) { clipboard.settext(fulldataurl); }
/// <summary> /// 清空文本框 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button_clear_click(object sender, eventargs e) { textbox1.clear(); fulldataurl = string.empty; }
以上就是详细介绍data url生成工具c#版第二版的示例代码的详细内容。