-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathForms.Main.pas
More file actions
230 lines (207 loc) · 6.88 KB
/
Forms.Main.pas
File metadata and controls
230 lines (207 loc) · 6.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
unit Forms.Main;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
FMX.Controls.Presentation, FMX.Objects, System.Actions, FMX.ActnList,
FMX.Layouts, FMX.Media, FMX.ListBox;
type
TMainForm = class(TForm)
Splitter1: TSplitter;
ToolBar1: TToolBar;
SubjectImage: TImage;
StatusLabel: TLabel;
MainActions: TActionList;
ActOpenFile: TAction;
BtnOpenFile: TSpeedButton;
OpenImageDialog: TOpenDialog;
SelectedTextHeading: TLabel;
SelectedTextLabel: TLabel;
TranslatedTextHeading: TLabel;
ContextLayout: TLayout;
TranslatedTextLabel: TLabel;
SpeechPlayer: TMediaPlayer;
TargetLanguageComboBox: TComboBox;
procedure SubjectImageMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Single);
procedure ActOpenFileExecute(Sender: TObject);
procedure SubjectImageClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure TargetLanguageComboBoxChange(Sender: TObject);
procedure FormShow(Sender: TObject);
private
FIsReady: Boolean;
FSelectedText: string;
FTranslatedText: string;
function GetImageTarget: TRectF;
function GetImageCoordinates(X, Y: Single): TPointF;
function GetRelativeImageCoordinates(X, Y: Single): TPointF;
procedure SetSelectedText(const ASelectedText: string);
procedure SetTranslatedText(const ATranslatedText: string);
property IsReady: Boolean read FIsReady;
property SelectedText: string read FSelectedText write SetSelectedText;
property TranslatedText: string read FTranslatedText write SetTranslatedText;
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
{$R *.fmx}
uses
DataModules.TextExtraction,
DataModules.Translation,
DataModules.TextToSpeech;
procedure TMainForm.ActOpenFileExecute(Sender: TObject);
begin
if OpenImageDialog.Execute then
begin
SubjectImage.Bitmap.LoadFromFile(OpenImageDialog.FileName);
if TextExtractionDM.ExtractText(OpenImageDialog.FileName) then
begin
StatusLabel.Text := 'Ready!';
FIsReady := True;
end
else
begin
StatusLabel.Text := 'Error.';
FIsReady := False;
end;
end;
end;
procedure TMainForm.TargetLanguageComboBoxChange(Sender: TObject);
var
LSpeechLanguageCode, LTranslationLanguageCode: string;
begin
LSpeechLanguageCode := TargetLanguageComboBox.Selected.Text.Split([':'])[0];
LTranslationLanguageCode := LSpeechLanguageCode.Split(['-'])[0];
TranslationDM.TargetLanguageCode := LTranslationLanguageCode;
TextToSpeechDM.LanguageCode := LSpeechLanguageCode;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
FIsReady := False;
end;
procedure TMainForm.FormShow(Sender: TObject);
begin
TranslationDM.TargetLanguageCode := 'en';
TextToSpeechDM.LanguageCode := 'en-GB';
end;
function TMainForm.GetImageCoordinates(X, Y: Single): TPointF;
var
LTargetRect: TRectF;
begin
if SubjectImage.Bitmap.Width = 0 then
Exit(TPointF.Create(-1, -1));
LTargetRect := GetImageTarget;
if (X >= LTargetRect.Left) and (X <= LTargetRect.Right) and (Y >= LTargetRect.Top) and (Y <= LTargetRect.Bottom) then
Result := TPointF.Create(
(X - LTargetRect.Left) / LTargetRect.Width * SubjectImage.Bitmap.Width,
(Y - LTargetRect.Top) / LTargetRect.Height * SubjectImage.Bitmap.Height
)
else
Result := TPointF.Create(-1, -1);
end;
function TMainForm.GetImageTarget: TRectF;
var
LTargetSize: TSizeF;
LControlAspectRatio, LImageAspectRatio: Single;
LScale: Single;
begin
LControlAspectRatio := SubjectImage.Width / SubjectImage.Height;
LImageAspectRatio := SubjectImage.Bitmap.Width / SubjectImage.Bitmap.Height;
if LImageAspectRatio > LControlAspectRatio then
begin
LScale := SubjectImage.Width / SubjectImage.Bitmap.Width;
LTargetSize := TSizeF.Create(SubjectImage.Width, SubjectImage.Bitmap.Height * LScale);
Result := TRectF.Create(
0,
(SubjectImage.Height - LTargetSize.Height) / 2,
SubjectImage.Width,
(SubjectImage.Height + LTargetSize.Height) / 2
);
end
else
begin
LScale := SubjectImage.Height / SubjectImage.Bitmap.Height;
LTargetSize := TSizeF.Create(SubjectImage.Bitmap.Width * LScale, SubjectImage.Height);
Result := TRectF.Create(
(SubjectImage.Width - LTargetSize.Width) / 2,
0,
(SubjectImage.Width + LTargetSize.Width) / 2,
SubjectImage.Height
);
end;
end;
function TMainForm.GetRelativeImageCoordinates(X, Y: Single): TPointF;
var
LTargetRect: TRectF;
begin
if SubjectImage.Bitmap.Width = 0 then
Exit(TPointF.Create(-1, -1));
LTargetRect := GetImageTarget;
if (X >= LTargetRect.Left) and (X <= LTargetRect.Right) and (Y >= LTargetRect.Top) and (Y <= LTargetRect.Bottom) then
Result := TPointF.Create(
(X - LTargetRect.Left) / LTargetRect.Width,
(Y - LTargetRect.Top) / LTargetRect.Height
)
else
Result := TPointF.Create(-1, -1);
end;
procedure TMainForm.SetSelectedText(const ASelectedText: string);
begin
FSelectedText := ASelectedText;
ContextLayout.BeginUpdate;
try
SelectedTextLabel.Text := FSelectedText;
if not FSelectedText.IsEmpty and TranslationDM.TranslateText(FSelectedText) then
TranslatedText := TranslationDM.TranslatedText
else
TranslatedText := '';
finally
ContextLayout.EndUpdate;
end;
end;
procedure TMainForm.SetTranslatedText(const ATranslatedText: string);
var
LAudioFileName: string;
begin
FTranslatedText := ATranslatedText;
if not FTranslatedText.IsEmpty then
begin
SelectedTextHeading.Text := Format('Selected Text (%s):', [TranslationDM.DetectedLanguageCode]);
TranslatedTextHeading.Text := Format('Translated Text (%s):', [TranslationDM.TargetLanguageCode]);
TranslatedTextLabel.Text := FTranslatedText;
if TextToSpeechDM.ConvertTextToSpeech(FTranslatedText, LAudioFileName) then
begin
SpeechPlayer.FileName := LAudioFileName;
SpeechPlayer.Play;
end;
end
else
begin
SelectedTextHeading.Text := 'Selected Text:';
TranslatedTextHeading.Text := 'Translated Text:';
TranslatedTextLabel.Text := 'N/A';
end;
end;
procedure TMainForm.SubjectImageClick(Sender: TObject);
var
LMousePos, LRelativeImageCoords: TPointF;
begin
if not IsReady then
Exit;
LMousePos := SubjectImage.ScreenToLocal(Screen.MousePos);
LRelativeImageCoords := GetRelativeImageCoordinates(LMousePos.X, LMousePos.Y);
SelectedText := TextExtractionDM.SelectTextAt(LRelativeImageCoords);
end;
procedure TMainForm.SubjectImageMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Single);
var
LImageCoords, LRelativeImageCoords: TPointF;
begin
LImageCoords := GetImageCoordinates(X, Y);
LRelativeImageCoords := GetRelativeImageCoordinates(X, Y);
StatusLabel.Text := Format('%f, %f (%f, %f)', [LImageCoords.X, LImageCoords.Y, LRelativeImageCoords.X, LRelativeImageCoords.Y]);
end;
end.