在 Delphi 中翻译语言
Posted
技术标签:
【中文标题】在 Delphi 中翻译语言【英文标题】:Translating Languages In Delphi 【发布时间】:2011-11-20 12:58:40 【问题描述】:我一直在寻找一些可以将任何语言翻译成另一种语言的代码,但我找到的代码都不起作用。 我知道 Google 有一个很好的翻译 API,但我无法让任何人的 Delphi 代码在它上面工作。 总会有一个错误出现在路上。 任何帮助将不胜感激,我需要一个可以尽快翻译我最终学校项目的程序。
【问题讨论】:
您能否向我们展示您目前拥有的东西,我们可以帮助您解决问题。我们不想为你做你的学校项目。 我认为你应该澄清你的问题。 IMO,您正在寻找通过调用 web 服务、DLL 或其他 API 来执行翻译的代码来进行翻译。 “可以将任何语言翻译成另一种语言的代码”可能需要语言学博士学位以及高级 CS 技能。 【参考方案1】:Google Translate API 是一个不错的选择,但现在只能作为付费服务使用。相反,您可以尝试使用 Microsoft Translator V2 API,查看这篇文章 Using the Microsoft Translator V2 API from delphi
了解有关如何从 delphi 使用此 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.
【讨论】:
好的,对于所有想要我收到的错误示例的人来说,这是我遇到 2 个错误的情况。 (我指的是theroadtodelphi.wordpress.com/2011/05/30/…)当我尝试这段代码时,我得到的第一个错误是类文件“Generics.Collections”不存在。我在谷歌上搜索了一个允许您下载 .pas 文件的网站,但我找不到任何内容。我得到的第二个错误,我认为我得到它是因为第一个错误,是在第 64 行(页面底部的完整代码)我得到一个错误,说有很多实际参数。 (续)显然编译器不知道 TEncoding.UTF8 是什么。我认为它必须在丢失的“Generics.Collections”文件中。 @MichaelMcQuirk 看来您使用的是旧版本的 delphi,请附上您的 delphi 版本以帮助您。 @RRUZ 请将Using the Microsoft Translator V2 API from delphi
的链接包含在您的答案中。【参考方案2】:
也许你没有找到 Marco Cantu 的作品?Works with REST/AJAX/Delphi
但正如 RRUZ 所说,Google Translate API 现在仅作为付费服务提供。
【讨论】:
谢谢,这段代码看起来很有前途,比谷歌翻译还多。给出的 exe 在我的电脑上 100% 工作,但是当我打开代码并尝试编译时,我得到一个错误,我想我错过了一个单元。它告诉我,在“TIdUri.ParamsEncode (strIn)”中,ParamsEncode 是一个未声明的标识符。它对稍后出现的“PosEx”也有同样的看法。 谢谢,我刚刚安装了 Delphi 7,这段代码运行良好。无论如何,它比 Google 的 API 更容易:) @MichaelMcQuirk,请注意,因为 marco cantu 页面中列出的项目使用的是已弃用的旧版 Google 语言 API 系列。 嘿,正如@RRUZ 所说,谷歌正在删除一些旧的 API,我不确定这会持续多久。因此,除了我认为这确实回答了您的问题之外,如果您想使用它,您应该进行更多研究。编辑:我之前在 Delphi 7 和 Delphi 2010 中对其进行了测试,并且运行良好。【参考方案3】:首先,您找不到 100% 的工具来将一种语言翻译成另一种语言。您可以拥有一个工具来为您完成一些(或多或少)工作,但您需要“打磨”其余部分。正如 RRUZ 所说,你可以使用微软的翻译器,但我所说的也适用于这种情况。任何这种类型的工具都会花钱。谷歌的翻译还不错,但需要付费。
PS:我不认为在学校他们会要求你创建一个可以将任何语言翻译成任何语言的工具。也许是一个小工具可以证明你明白了这个概念。只是我的 2 美分...
【讨论】:
嗯,实际上我的项目是我需要制作一个可以教用户一门新语言的程序。使用 Google Translate 的 API 只是该程序的一小部分(但非常重要)组件之一。大部分项目已经完成,我只需要一种翻译文本的方法。以上是关于在 Delphi 中翻译语言的主要内容,如果未能解决你的问题,请参考以下文章