「桌面」怎样写一个自己的PC版百度翻译软件

  • 为什么要用百度翻译?

从前是百度粉,现在我是百度黑,百度要完!

但是(真香),在各种翻译App中,我真的觉得百度的翻译最准确~~

不过也可能是个人喜好吧,勿喷。

  • 为啥要搞PC版?

因为英语能力有限,经常看外文的资料确实需要一个翻译软件,另一个,我记得以前是有PC端的百度翻译的,但是不知道为啥没有了。现在在用有道的,但是经常有比较智障。

所以,不如自己搞一个吧,先实现最简单的需求就好。

1、获取百度翻译API接口

网址:http://api.fanyi.baidu.com/api/trans/product/index

“通用”版本的功能基本够用,主要 免费!

注册个账号,然后你会得到属于你的 “AppID”和“密钥”

并且可以在“文档与支持”中找到Demo示例,有各种语言的。

2、创建程序并设计界面

简单点,搞一个WinForm程序

扫描二维码关注公众号,回复: 10111355 查看本文章

上下两个文本框,为了实现随着窗口大小自动变化,并且上下比例能随意拖动,是放在一个【SplitContainer】中的

3、翻译功能的实现

先贴代码,后面说明

using System;
using System.Text;
using System.Net;
using System.IO;
using System.Security.Cryptography;
using System.Web;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Linq;

namespace Transink
{
    //用于解析返回的Json数据
    public class TransResult
    {
        public string src { get; set; }
        public string dst { get; set; }
    }

    public class BDTrans
    {
        //错误代码
        private KeyValuePair<string, string>[] ErroCodes;
        private string appId; //AppID
        private string secretKey;  //密钥
        private string apiAdd;  //Api地址

        public BDTrans()
        {
            appId = "20191016000342007";
            secretKey = "uva6gEvgtMGAHHIhh0zK";
            apiAdd = "https://fanyi-api.baidu.com/api/trans/vip/translate?";
            InitErroCode();//把错误代码对应的信息加载一下
        }
        
        //src=原文本 from=原语言  to=目标语言
        //将接受的返回以字符串返回
        public string Translate(string src, string from, string to)
        {
            string url = apiAdd;
            Random rd = new Random();
            string salt = rd.Next(100000).ToString();
            string sign = EncryptString(appId + src + salt + secretKey);
            url += "q=" + HttpUtility.UrlEncode(src);
            url += "&from=" + from;
            url += "&to=" + to;
            url += "&appid=" + appId;
            url += "&salt=" + salt;
            url += "&sign=" + sign;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";
            request.ContentType = "text/html;charset=UTF-8";
            request.UserAgent = null;
            request.Timeout = 6000;
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();
            return ParseResponse(retString);
        }

        //解析反馈
        private string ParseResponse(string resStr)
        {
            JObject retJson = JObject.Parse(resStr);
            List<JToken> tokens = new List<JToken>();
            List<TransResult> transResults = new List<TransResult>();
            string res = "";
            //如果有结果
            if (resStr.Contains("trans_result"))
            {
                tokens = retJson["trans_result"].Children().ToList();
                foreach (JToken token in tokens)
                {
                    transResults.Add(token.ToObject<TransResult>());
                    res += token.ToObject<TransResult>().dst +"\r\n";
                }
                
            }
            //如果错误
            if (resStr.Contains("error_code"))
            {
                JToken token = retJson["error_code"];
                string erroCode = token.ToObject<string>();
                //根据错误代码查询对应信息
                var ErroStauts = ErroCodes.Where<KeyValuePair<string, string>>(x => x.Key == erroCode);
                if (ErroStauts.Count() == 0)
                {
                    res = "Unknown Error";
                }
                else
                {
                    res = "Error: " + ErroStauts.ToList()[0].Value;
                }
            }
            return res;
        }

        //进行MD5加密
        public static string EncryptString(string str)
        {
            MD5 md5 = MD5.Create();
            // 将字符串转换成字节数组
            byte[] byteOld = Encoding.UTF8.GetBytes(str);
            // 调用加密方法
            byte[] byteNew = md5.ComputeHash(byteOld);
            // 将加密结果转换为字符串
            StringBuilder sb = new StringBuilder();
            foreach (byte b in byteNew)
            {
                // 将字节转换成16进制表示的字符串,
                sb.Append(b.ToString("x2"));
            }
            // 返回加密的字符串
            return sb.ToString();
        }

        //初始化错误代码映射字典
        private void InitErroCode()
        {
            ErroCodes = new KeyValuePair<string, string>[]
                {
                    new KeyValuePair<string, string>("52001", "请求超时"),
                    new KeyValuePair<string, string>("52002", "系统错误"),
                    new KeyValuePair<string, string>("52003", "未授权用户"),
                    new KeyValuePair<string, string>("54000", "必填参数为空 "),
                    new KeyValuePair<string, string>("54001", "签名错误"),
                    new KeyValuePair<string, string>("54003", "访问频率受限"),
                    new KeyValuePair<string, string>("54004", "账户余额不足"),
                    new KeyValuePair<string, string>("54005", "长query请求频繁"),
                    new KeyValuePair<string, string>("58000", "客户端IP非法 "),
                    new KeyValuePair<string, string>("58001", "译文语言方向不支持"),
                    new KeyValuePair<string, string>("58002", "服务当前已关闭"),
                    new KeyValuePair<string, string>("90107", "认证未通过或未生效")
                };
        }

        //根据字符判断所属语言,只实现中(2)英(1)文,其他的的统一为一类(0)
        private int detectLanguageChar(char c)
        {
            int index = Convert.ToInt32(c);
            if (index > 13312 && index < 40895)
            {
                return 2;
            }
            else if (index > 65 && index < 122)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }

        //判断原文本可能是什么语言(那种语言的字符占的多)
        public string detectLanguage(string str)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(str);
            char[] chars = Encoding.UTF8.GetChars(bytes);
            int[] langP = new int[3] { 0, 0, 0 };
            for (int i = 0; i < chars.Length; i++)
            {
                langP[detectLanguageChar(chars[i])] += 1;
            }
            int lang = -1;int max = 0;
            for (int i = 0; i < langP.Length; i++)
            {
                if (langP[i] > max)
                {
                    max = langP[i];lang = i;
                }
            }
            switch (lang)
            {
                case 1:
                    return "en";
                case 2:
                    return "zh";
                default:
                    return "auto";
            }

        }
    }
}

首先

【Translate】方法: 就是执行翻译的主方法,进行url拼接、加密、发送请求,接收反馈,最后以字符串形式返回。具体可参考官方的文档。

【ParseResponse】方法: 就是解析反馈的内容,反馈是Json格式,使用了【Newtonsoft.Json】第三方包来解析Json字符串

【detectLanguage】方法: 检测当前输入的是什么语言,本来希望能识别出所有语言,但是发现貌似没那么简单,另外,我的需求也只是要自动识别中英文,把不是中文的翻译成中文,把中文自动翻译成英文,如果有需要,再指定语言就好。

具体怎么识别呢,调用【detectLanguageChar】方法,通过字符的UTF-8编码,中文大概是u4E00-u9FA5 和0x3400, 0x4DB5,取个大概,转换成10进制 (13312~40895)吧,英文26个大小写字母在41~5A和61~7A,取个大概,转换成10进制(65~122),然后根据输入的文本中,哪种字符占比多进行判断。

4、完成整个程序

也就是Form1.cs中的代码

4.1、窗口初始化和支持的语言列表

BDTrans trans;

//支持的语言映射列表
List<KeyValuePair<string, string>> LangList;

public Form1()
{
    InitializeComponent();
    //初始化语言列表
    InitLangs();
    trans = new BDTrans();
}

//初始化并给两个ComboBox添加
public void InitLangs()
{
    LangList = new List<KeyValuePair<string, string>>();
    KeyValuePair<string, string>[] langs = new KeyValuePair<string, string>[]
        {
            new KeyValuePair<string,string>("auto","自动检测"),
            new KeyValuePair<string,string>("zh","中文"),
            new KeyValuePair<string,string>("en","英语"),
            new KeyValuePair<string,string>("yue","粤语"),
            new KeyValuePair<string,string>("wyw","文言文"),
            new KeyValuePair<string,string>("jp","日语"),
            new KeyValuePair<string,string>("kor","韩语"),
            new KeyValuePair<string,string>("fra","法语"),
            new KeyValuePair<string,string>("spa","西班牙语"),
            new KeyValuePair<string,string>("th","泰语"),
            new KeyValuePair<string,string>("ara","阿拉伯语"),
            new KeyValuePair<string,string>("ru","俄语"),
            new KeyValuePair<string,string>("pt","葡萄牙语"),
            new KeyValuePair<string,string>("de","德语"),
            new KeyValuePair<string,string>("it","意大利语"),
            new KeyValuePair<string,string>("el","希腊语"),
            new KeyValuePair<string,string>("nl","荷兰语"),
            new KeyValuePair<string,string>("pl","波兰语"),
            new KeyValuePair<string,string>("bul","保加利亚语"),
            new KeyValuePair<string,string>("est","爱沙尼亚语"),
            new KeyValuePair<string,string>("dan","丹麦语"),
            new KeyValuePair<string,string>("fin","芬兰语"),
            new KeyValuePair<string,string>("cs","捷克语"),
            new KeyValuePair<string,string>("rom","罗马尼亚语"),
            new KeyValuePair<string,string>("slo","斯洛文尼亚语"),
            new KeyValuePair<string,string>("swe","瑞典语"),
            new KeyValuePair<string,string>("hu","匈牙利语"),
            new KeyValuePair<string,string>("cht","繁体中文"),
            new KeyValuePair<string,string>("vie","越南语")
        };
    for (int i = 0; i < langs.Length; i++)
    {
        LangList.Add(langs[i]);
        coBox_SrcLang.Items.Add(langs[i].Value);
        coBox_DstLang.Items.Add(langs[i].Value);
    }
    coBox_SrcLang.SelectedIndex = 0;
    coBox_DstLang.SelectedIndex = 1;
}

4.2、 自动翻译

给【tBox_Src】编辑框添加【TextChanged】事件

//中英文自动翻译
private void tBox_Src_TextChanged(object sender, EventArgs e)
{
    string src = tBox_Src.Text;
    string from = "en";
    string to = "zh";
    if (src != "")
    {
        ///判断原语言
        from = trans.detectLanguage(tBox_Src.Text);
        if (from == "zh")
        { to = "en"; }
        //根据检测到的语言 更新一下 comBox_SrcLang和comBox_DstLang
        coBox_SrcLang.SelectedItem = LangList.Where<KeyValuePair<string, string>>(x => x.Key == from).ToList()[0].Value;
        coBox_DstLang.SelectedItem = LangList.Where<KeyValuePair<string, string>>(x => x.Key == to).ToList()[0].Value;
        string dst = trans.Translate(src, from, to);
        tBox_Dst.Text = dst;
    }
    else
    {
        tBox_Dst.Text = "";
    }


}

4.3、 手动指定语言翻译

给【btn_Trans】按钮添加click事件:

private void btn_Trans_Click(object sender, EventArgs e)
{
    string from = LangList[coBox_SrcLang.SelectedIndex].Key;
    string to = LangList[coBox_DstLang.SelectedIndex].Key;
    string src = tBox_Src.Text;
    if (src != "")
    {                
        string dst = trans.Translate(src, from, to);
        tBox_Dst.Text = dst;
    }
    else
    {
        tBox_Dst.Text = "";
    }
}

4.4、让程序常驻

不能翻译两句,一不小心点关闭,又得重新开,

所以上一篇就用上了,让程序点关闭时,缩小到右下角通知栏

5、大功告成

翻译一下看看~

发布了21 篇原创文章 · 获赞 5 · 访问量 3666

猜你喜欢

转载自blog.csdn.net/Raink_LH/article/details/103498437