在 Delphi 中翻译语言

6

我已经寻找了很久的时间,希望能找到一些可以将任何语言翻译成另一种语言的代码,但是我找到的所有代码都无法正常工作。
我知道谷歌有一个很好的翻译API,但我无法让任何人的Delphi代码正常工作。
总会出现错误阻碍进程。 非常感谢任何帮助,我需要一个能够尽快翻译的程序来完成我的最终学校项目。


你能展示一下你目前的进展吗?我们可以帮助你解决问题。但我们不想替你完成学校项目。 - David Heffernan
我认为你应该澄清你的问题。在我看来,你正在寻找通过调用Web服务、DLL或其他API进行翻译的代码。"能够将任何语言翻译成另一种语言的代码"可能需要除了高级计算机技能外还需要语言学博士学位。 - Chris Thornton
3个回答

11
谷歌翻译API是一个不错的选择,但现在只提供付费服务。相反,您可以尝试使用Microsoft Translator V2 API,有关如何从Delphi使用此API的详细信息,请查看本文“使用Delphi中的Microsoft Translator V2 API”

更新 这是同一篇文章的演示项目,经过修改以与您的Delphi版本兼容。

program MicrosoftTranslatorApi;

{$APPTYPE CONSOLE}

uses
  ShellApi,
  ActiveX,
  Classes,
  ComObj,
  Variants,
  Windows,
  WinInet,
  SysUtils;

const
   MicrosoftTranslatorTranslateUri = 'http://api.microsofttranslator.com/v2/Http.svc/Translate?appId=%s&text=%s&from=%s&to=%s';
   MicrosoftTranslatorDetectUri    = 'http://api.microsofttranslator.com/v2/Http.svc/Detect?appId=%s&text=%s';
   MicrosoftTranslatorGetLngUri    = 'http://api.microsofttranslator.com/v2/Http.svc/GetLanguagesForTranslate?appId=%s';
   MicrosoftTranslatorGetSpkUri    = 'http://api.microsofttranslator.com/v2/Http.svc/GetLanguagesForSpeak?appId=%s';
   MicrosoftTranslatorSpeakUri     = 'http://api.microsofttranslator.com/v2/Http.svc/Speak?appId=%s&text=%s&language=%s';
   //this AppId if for demo only please be nice and use your own , it's easy get one from here http://msdn.microsoft.com/en-us/library/ff512386.aspx
   BingAppId                       = '73C8F474CA4D1202AD60747126813B731199ECEA';
   Msxml2_DOMDocument              = 'Msxml2.DOMDocument.6.0';

procedure WinInet_HttpGet(const Url: string;Stream:TStream);overload;
const
BuffSize = 1024*1024;
var
  hInter   : HINTERNET;
  UrlHandle: HINTERNET;
  BytesRead: DWORD;
  Buffer   : Pointer;
begin
  hInter := InternetOpen('', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if Assigned(hInter) then
    try
      Stream.Seek(0,0);
      GetMem(Buffer,BuffSize);
      try
          UrlHandle := InternetOpenUrl(hInter, PChar(Url), nil, 0, INTERNET_FLAG_RELOAD, 0);
          if Assigned(UrlHandle) then
          begin
            repeat
              InternetReadFile(UrlHandle, Buffer, BuffSize, BytesRead);
              if BytesRead>0 then
               Stream.WriteBuffer(Buffer^,BytesRead);
            until BytesRead = 0;
            InternetCloseHandle(UrlHandle);
          end;
      finally
        FreeMem(Buffer);
      end;
    finally
     InternetCloseHandle(hInter);
    end;
end;

function WinInet_HttpGet(const Url: string): string;overload;
Var
  StringStream : TStringStream;
begin
  Result:='';
    StringStream:=TStringStream.Create('');
    try
        WinInet_HttpGet(Url,StringStream);
        if StringStream.Size>0 then
        begin
          StringStream.Seek(0,0);
          Result:=StringStream.ReadString(StringStream.Size);
        end;
    finally
      StringStream.Free;
    end;
end;

function TranslateText(const AText,SourceLng,DestLng:string):string;
var
   XmlDoc : OleVariant;
   Node   : OleVariant;
begin
  Result:=WinInet_HttpGet(Format(MicrosoftTranslatorTranslateUri,[BingAppId,AText,SourceLng,DestLng]));
  XmlDoc:= CreateOleObject(Msxml2_DOMDocument);
  try
    XmlDoc.Async := False;
    XmlDoc.LoadXML(Result);
    if (XmlDoc.parseError.errorCode <> 0) then
     raise Exception.CreateFmt('Error in Xml Data %s',[XmlDoc.parseError]);
    Node:= XmlDoc.documentElement;
    if not VarIsClear(Node) then
     Result:=XmlDoc.Text;
  finally
     XmlDoc:=Unassigned;
  end;
end;

function DetectLanguage(const AText:string ):string;
var
   XmlDoc : OleVariant;
   Node   : OleVariant;
begin
  Result:=WinInet_HttpGet(Format(MicrosoftTranslatorDetectUri,[BingAppId,AText]));
  XmlDoc:= CreateOleObject(Msxml2_DOMDocument);
  try
    XmlDoc.Async := False;
    XmlDoc.LoadXML(Result);
    if (XmlDoc.parseError.errorCode <> 0) then
     raise Exception.CreateFmt('Error in Xml Data %s',[XmlDoc.parseError]);
    Node:= XmlDoc.documentElement;
    if not VarIsClear(Node) then
      Result:=XmlDoc.Text;
  finally
     XmlDoc:=Unassigned;
  end;
end;

function GetLanguagesForTranslate: TStringList;
var
   XmlDoc : OleVariant;
   Node   : OleVariant;
   Nodes  : OleVariant;
   lNodes : Integer;
   i      : Integer;
   sValue : string;
begin
  Result:=TStringList.Create;
  sValue:=WinInet_HttpGet(Format(MicrosoftTranslatorGetLngUri,[BingAppId]));
  XmlDoc:= CreateOleObject(Msxml2_DOMDocument);
  try
    XmlDoc.Async := False;
    XmlDoc.LoadXML(sValue);
    if (XmlDoc.parseError.errorCode <> 0) then
     raise Exception.CreateFmt('Error in Xml Data %s',[XmlDoc.parseError]);
    Node:= XmlDoc.documentElement;
    if not VarIsClear(Node) then
    begin
      Nodes := Node.childNodes;
       if not VarIsClear(Nodes) then
       begin
         lNodes:= Nodes.Length;
           for i:=0 to lNodes-1 do
            Result.Add(Nodes.Item(i).Text);
       end;
    end;
  finally
     XmlDoc:=Unassigned;
  end;
end;

function GetLanguagesForSpeak: TStringList;
var
   XmlDoc : OleVariant;
   Node   : OleVariant;
   Nodes  : OleVariant;
   lNodes : Integer;
   i      : Integer;
   sValue : string;
begin
  Result:=TStringList.Create;
  sValue:=WinInet_HttpGet(Format(MicrosoftTranslatorGetSpkUri,[BingAppId]));
  XmlDoc:= CreateOleObject(Msxml2_DOMDocument);
  try
    XmlDoc.Async := False;
    XmlDoc.LoadXML(sValue);
    if (XmlDoc.parseError.errorCode <> 0) then
     raise Exception.CreateFmt('Error in Xml Data %s',[XmlDoc.parseError]);
    Node:= XmlDoc.documentElement;
    if not VarIsClear(Node) then
    begin
      Nodes := Node.childNodes;
       if not VarIsClear(Nodes) then
       begin
         lNodes:= Nodes.Length;
           for i:=0 to lNodes-1 do
            Result.Add(Nodes.Item(i).Text);
       end;
    end;
  finally
     XmlDoc:=Unassigned;
  end;
end;

procedure Speak(const FileName,AText,Lng:string);
var
  Stream : TFileStream;
begin
  Stream:=TFileStream.Create(FileName,fmCreate);
  try
    WinInet_HttpGet(Format(MicrosoftTranslatorSpeakUri,[BingAppId,AText,Lng]),Stream);
  finally
     Stream.Free;
  end;
end;

var
 lng       : TStringList;
 i         : Integer;
 FileName  : string;

begin
 try
    CoInitialize(nil);
    try
      Writeln(TranslateText('Hello World','en','es'));
      Writeln(DetectLanguage('Hello World'));

      Writeln('Languages for translate supported');
      lng:=GetLanguagesForTranslate;
      try
        for i:=0 to lng.Count-1 do
         Writeln(lng[i]);
      finally
        lng.free;
      end;

      Writeln('Languages for speak supported');
      lng:=GetLanguagesForSpeak;
      try
        for i:=0 to lng.Count-1 do
         Writeln(lng[i]);
      finally
        lng.free;
      end;

      FileName:=ExtractFilePath(ParamStr(0))+'Demo.wav';
      Speak(FileName,'This is a demo using the Microsoft Translator Api from delphi, enjoy','en');
      ShellExecute(0, 'open', PChar(FileName),nil,nil, SW_SHOWNORMAL) ;

    finally
      CoUninitialize;
    end;
 except
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.

好的,对于那些想要看到我收到的错误示例的人,这里有一个案例,我收到了两个错误。 (我指的是http://theroadtodelphi.wordpress.com/2011/05/30/using-the-microsoft-translator-v2-from-delphi/)当我尝试此代码时,我收到的第一个错误是类文件“Generics.Collections”不存在。 我已经搜索了一个允许您下载.pas文件的网站,但我找不到任何内容。 我得到的第二个错误,我认为是由于第一个错误,是在第64行(完整代码在页面底部)我收到了一个错误,说有太多实际参数。 - Michael McQuirk
(续)显然编译器不知道TEncoding.UTF8是什么。我认为它必须在缺失的“Generics.Collections”文件中。 - Michael McQuirk
@MichaelMcQuirk,看起来您正在使用旧版本的Delphi,请提供您的Delphi版本以帮助您。 - RRUZ
@RRUZ,请将“从Delphi使用Microsoft Translator V2 API”的链接包含在您的回答中。 - Ilyes

3

谢谢,这段代码看起来非常有前途,比谷歌翻译更好。给出的exe在我的电脑上可以100%运行,但是当我打开代码并尝试编译时,我遇到了一个错误,我认为我缺少一个单元。它告诉我在“TIdUri.ParamsEncode(strIn)”中ParamsEncode是未声明的标识符。后面出现的“PosEx”也是一样。 - Michael McQuirk
谢谢,我刚安装了 Delphi 7,这段代码完美运行。无论如何,它比谷歌的 API 更容易使用 :) - Michael McQuirk
@MichaelMcQuirk,请注意,因为Marco Cantu页面列出的项目使用了已经被弃用的Google语言API家族的旧版本。 - RRUZ
嘿,正如@RRUZ所说,Google正在关闭一些旧API,我不确定这将持续多久。所以,除了我认为这真的回答了你的问题之外,如果你想使用它,你应该再做更多的研究。 编辑:我在Delphi 7和Delphi 2010中测试过,完美地工作。 - EMBarbosa

0
首先,你无法找到一个100%的工具来从一种语言翻译成另一种语言。你可以使用一个工具来完成部分(多或少)的工作,但你需要“打磨”剩下的部分。正如RRUZ所说,你可以使用微软的翻译器,但我所说的也适用于这种情况。任何这种类型的工具都会花费你的金钱。谷歌的翻译很不错,但你需要为此付费。
附注:我不认为在学校里会要求你创建一个能够将任何语言翻译成任何语言的工具。也许只需要一个小工具来证明你掌握了概念。仅代表个人观点...

实际上,我的项目是需要制作一个可以教用户学习新语言的程序。使用Google翻译API只是该程序中小但非常重要的组成部分之一。大部分项目已经完成,我只需要一种翻译文本的方法。 - Michael McQuirk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接