IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]Data Url生成工具C#版 第二版

    testcs_dn发表于 2015-04-25 07:29:22
    love 0

    为什么有第二版


      首先感谢 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#版 第二版完整源码下载
    资源分定的比较高,下载后评论会返还的。

    相关文章


    用Visual Studio 2010编写Data Url生成工具C#版
    检测到 ContextSwitchDeadlock
    Data Url生成工具之HTML5 FileReader实现

    提出一个问题


    C#如何高效的向TextBox写入一个很长的字符串?

    鄙人不才,几番努力都未能解决这个问题,特在此向大家学习请教!



沪ICP备19023445号-2号
友情链接