-
Notifications
You must be signed in to change notification settings - Fork 0
/
Editor.cpp
475 lines (437 loc) · 17.4 KB
/
Editor.cpp
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
#include"Editor.h"
std::vector<Session> Editor::session;
std::string Editor::command;
Formats* Editor::loadAccordingToFormat(std::string path)
{//Âðúùà îáåêò êúì ôîðìàòà, êîéòî ñúîòâåòñòâà íà çàäàäåíèÿ àäðåñ.
if (findFormat(path) == "ppm")
{
return new PPM;
}
else if (findFormat(path) == "pgm")
{
return new PGM;
}
else if (findFormat(path) == "pbm")
{
return new PBM;
}
else return nullptr;
}
bool Editor::isCommand(std::string command)//Ïðîâåðÿâà çà êîðåêòíîñò íà êîìàíäíèÿ ðåä.
{
return command == "load" || command == "close" || command == "save" || command == "saveas" || command == "help" || command == "exit"
|| command == "grayscale" || command == "monochrome" || command == "negative" || command == "rotate"
|| command == "undo" || command == "add" || command == "session" || command == "info" || command == "switch"
|| command == "collage";
}
void Editor::help()//Èçâåæäà êðàòêà èíôîðìàöèÿ çà ïîääúðæàíèòå îò ïðîãðàìàòà êîìàíäè.
{
std::cout << "load <image> create session with unique ID.\n"
<< "close --> closes currently opened file.\n"
<< "save --> saves the currentrly load file.\n"
<< "saveas <file> --> saves the currently load file in <file>.\n"
<< "help --> prints this information.\n"
<< "exit --> exist the program.\n"
<< "grayscale --> change the image to grayscale.\n"
<< "monochrome --> change the image to monochrome.\n"
<< "negative --> change the image to negative.\n"
<< "rotate <direction> --> rotate image right ot left.\n"
<< "undo --> return command back.\n"
<< "add <image> --> add image to session.\n"
<< "session info --> display information about session.\n"
<< "switch <session> --> switch session to another with ID <session>.\n"
<< "collage <direction> <image1> <image2> <outimage> "
<< "--> create collage with horizontal ot vertical <direction> and save them in new image <outimage>.\n";
}
std::string Editor::findFormat(std::string path)//Âðúùà ðàçøèðåíèåòî íà ôàéëà.
{
std::string helper;//Ïîìîùíà ïðîìåíëèâà, â êîÿòî çàïàçâàìå ðàçøèðåíèåòî.
for (int i = path.size() - 1; i >= 0; i--)
{
if (path[i] == '.')break;//Öèêëè îòçàä íàïðåä, äîêàòî ñòèãíå äî òî÷êà.
helper = path[i] + helper;
}
return helper;
}
bool Editor::isCorrectFileExtension(std::string extension)//Ïðîâåðÿâà äàëè ïîäàäåíîòî ðàçøèðåíèå ñå ïîääúðæà îò ïðîãðàìàòà.
{
return extension == "ppm" || extension == "pgm" || extension == "pbm";
}
std::vector<std::string> Editor::findPath(std::string paths)//Àêî â åäèí ñòðèíã èìà íÿêîëêà àäðåñà, ò.å. íÿêîëêî ñíèìêè, òî òàçè ôóíêöèÿ ãè îòäåëÿ.
{
std::vector<std::string> saver;//Ïðîìåíëèâà, â êîÿòî çàïàçâàìå âñåêè îòäåëåí àäðåñ è ÿ âðúùàìå êàòî ðåçóëòàò.
std::string helper;//Ïðîìåíëèâà, â êîÿòî çàïàçâàìå åäèíè÷íèÿ àäðåñ.
std::string help;//Ïðîìåíëèâà, â êîÿòî çàïàçâàìå ðàçøèðåíèå, çà äà ñðàâíÿâàìå çà êîðåêòíîñò.
for (int i = paths.size() - 1; i >= 0; i--)//Îáõîæäàìå îòçàä íàïðåä.
{
if (paths[i] != ' ')//Äîêàòî íå ñòèãíåì äî èíòåðâàë, äîáàâÿìå âñÿêà áóêâà â ïðîìåíëèâàòà "helper".
{
helper = paths[i] + helper;
}
else if (paths[i] == ' ')/*Àêî ñòèãíåì äî èíòåðâàë, ïðîâåðÿâàìå äàëè ñëåäâàùèòå áóêâè, êîèòî ïðåäñòîÿò,
îáðàçóâàò êîðåêòíî ðàçøèðåíèå è àêî îáðàçóâàò, òî çíà÷è ñëåäâà äà áúäå èç÷åòåí íîâ àäðåñ è çàòîâà â ïðîìåíëèâàòà
"helper" èìàìå îòäåëåí åäèí àäðåñ, êîéòî äîáàâÿìå êúì ïðîìåíëèâàòà "saver" è èç÷èñòâàìå "helper",
çà äà ìîæå îòíîâî äà ÿ ïîëçâàìå, àêî íå - òî çíà÷è ïðîñòî â àäðåñà èìà ïðàçíî ìÿñòî è ïðîäúëæàâàìå äà ãî îáðàçóâàìå.*/
{
help.clear();
for (int j = i - 1; j >= i - 3 && j >= 0; j--)
{
help = paths[j] + help;
}
if (isCorrectFileExtension(help))
{
saver.push_back(helper);
helper.clear();
}
else
{
helper = paths[i] + helper;
}
}
}
saver.push_back(helper);
return saver;
}
bool Editor::isCorrectFileFormat(std::string path)//Ïðîâåðÿâà ïî äàäåí àäðåñ äàëè å êîðåêòíî ðàçøèðåíèåòî.
{
return findFormat(path) == "ppm" || findFormat(path) == "pgm" || findFormat(path) == "pbm";
}
void Editor::addEffectToPPM(Session& other, std::string effect)//Ïîìîùíà ôóíêöèÿ çà äîáàâÿíå íà òðàíñôîðìàöèÿ â äàäåíà ñåñèÿ.
{//Èçïîëçâà ñå ñàìî ïðè ".ppm" ôîðìàò, êîãàòî èçïúëíÿâàìå ôóíêöèèòå "grayscale" è "monochrome", çàùîòî òå ñå îòíàñÿò ñàìî çà òîçè ôîðìàò.
for (size_t i = 0; i < other.Formats().size(); i++)
{
if (findFormat(other.Formats()[i]->getPath()) == "ppm")
{
other.Transformations().push_back(effect);
break;
}
}
}
bool Editor::read(std::string path)//Ïðîâåðÿâà äàëè ñúñòîÿíèåòî íà ïîòîêà å äîáðî.
{
std::ifstream input(path.c_str());
return input.good();
}
int Editor::countExistedImage(std::vector<std::string> path)
{
//Áðîÿ÷, ÷ðåç êîéòî ïðîâåðÿâàìå äàëè ïðè âúâåæäàíå íà èçîáðàæåíèÿòà, èìà òàêîâà ñ âàëèäåí àäðåñ, çàùîòî àêî íÿìà, òî ñåñèÿ áåç ñíèìêè å áåçñìèñëåíî.
int counter = 0;
for (size_t i = 0; i < path.size(); i++)
{
if (isCorrectFileFormat(path[i]) && read(path[i]))
{
counter++;
}
}
return counter;
}
void Editor::commandGrayscale(Session& other)
{
for (size_t i = 0; i < other.Formats().size(); i++)
{
other.Formats()[i]->grayscale();
}
addEffectToPPM(other, "grayscale");//Äîáàâÿ, ÷å å èçâúðøåíà òðàíñôîðìàöèÿ ñàìî àêî èìà ïîíå åäíî èçîáðàæåíèå îò ".ppm" ôîðìàò.
}
void Editor::commandMonochrome(Session& other)
{
for (size_t i = 0; i < other.Formats().size(); i++)
{
other.Formats()[i]->monochrome();
}
addEffectToPPM(other, "monochrome"); //Äîáàâÿ, ÷å å èçâúðøåíà òðàíñôîðìàöèÿ ñàìî àêî èìà ïîíå åäíî èçîáðàæåíèå îò ".ppm" ôîðìàò.
}
void Editor::commandNegative(Session& other)
{
for (size_t i = 0; i < other.Formats().size(); i++)
{
other.Formats()[i]->negative();
}
other.Transformations().push_back("negative");
}
void Editor::commandSaveas(Session& other, std::string paths)
{
std::cin.ignore();
std::getline(std::cin, paths);//Âúâåæäàìå êúäå è ñ êàêâî èìå èñêàìå äà çàïàçèì ïúðâîòî çàðåäåíî èçîáðàæåíèå â ñåñèÿòà.
if (findFormat(paths) == findFormat(other.Formats()[0]->getPath()))
{//Àêî èìà ñúâïàäåíèå íà ðàçøèðåíèåòî íà èçîáðàæåíèåòî è âúâåäåíîòî ðàçøèðåíèå, òî òîãàâà ãî çàïèñâàìå.
other.Formats()[0]->saveas(paths);
std::cout << "Successfully saved another " << other.Formats()[0]->getPath() << '\n';
other.Transformations().clear();
}
else std::cout << "Incorrect file format!\n";
}
void Editor::commandSave(Session& other)
{
for (size_t i = 0; i < other.Formats().size(); i++)
{
other.Formats()[i]->saveas(other.Formats()[i]->getPath());
std::cout << "Successfully saved " << other.Formats()[i]->getPath() << '\n';
}
other.Transformations().clear();
}
void Editor::commandAdd(Session& other, std::string paths)
{
if (isCorrectFileFormat(paths) && read(paths))
{
other.Formats().push_back(loadAccordingToFormat(paths));
other.Formats().back()->load(paths);
other.addTransformations("add");
std::cout << "Successfully added: " << other.Formats().back()->getPath() << '\n';
}
else
{
std::cout << "Unsuccessfully added!: " << paths << '\n';
}
}
void Editor::commandRotation(Session& other)
{
std::string direction;
std::cin.ignore();
std::cin >> direction;
for (size_t i = 0; i < other.Formats().size(); i++)
{
other.Formats()[i]->rotation(direction);
}
std::string helper = command + " " + direction;
other.addTransformations(helper);
}
void Editor::commandSwitchSession()
{
size_t id;
std::cin.ignore();
std::cin >> id;
if (id >= 1 && id <= session.size())
{
std::cout << "You switch to session with ID: " << id << "!\n";
std::cout << "Name of images in the session ";
for (size_t i = 0; i < session[id - 1].Formats().size(); i++)
{
std::cout << session[id - 1].Formats()[i]->getPath() << " ";
}
std::cout << "\nPending transformations: ";
for (size_t i = 0; i < session[id - 1].Transformations().size(); i++)
{
std::cout << session[id - 1].Transformations()[i] << ", ";
}
std::cout << '\n';
}
else
{
std::cout << "Incorrect session with id " << id << '\n';
}
}
void Editor::commandUndo(Session& other)
{
if (other.Transformations().size() != 0)//Àêî èìà ïîíå åäíà ïðîìÿíà:
{
std::string helper = other.Transformations().back();//Ïðåìàõâàìå ÿ îò ñïèñúêà ñ òðàíñôîðìàöèè.
//Â çàâèñèìîñò îò íàïðàâåíàòà òðàíñôîðìàöèÿ, ïðåìàõâà ïðîìåíèòå.
if (helper == "grayscale")
{
for (size_t i = 0; i < other.Formats().size(); i++)
{
other.Formats()[i]->undoGrayscale();
}
}
else if (helper == "monochrome")
{
for (size_t i = 0; i < other.Formats().size(); i++)
{
other.Formats()[i]->undoMonochrome();
}
}
else if (helper == "negative")
{
for (size_t i = 0; i < other.Formats().size(); i++)
{
other.Formats()[i]->negative();
}
}
else if (helper == "rotate right")
{
for (size_t i = 0; i < other.Formats().size(); i++)
{
other.Formats()[i]->rotation("left");
}
}
else if (helper == "rotate left")
{
for (size_t i = 0; i < other.Formats().size(); i++)
{
other.Formats()[i]->rotation("right");
}
}
else if (helper == "add")
{
other.Formats().pop_back();
}
other.Transformations().pop_back();
}
else std::cout << "Cannot undo!\n";//Àêî íÿìà òðàíôîðìàöèè.
}
void Editor::commandCollage(Session& other)
{
std::string direction;//Ïðîìåíëèâà, êîÿòî èçïîëçâàìå, êîãàòî âúâåæäàìå ïîñîêà íà ñúçäàâàíå íà êîëàæ.
std::string path;//Ïðîìåíëèâà, â êîÿòî â íà÷àëîòî ùå èìàìå 3 àäðåñà.
std::vector<std::string> paths;
std::cin.ignore();
std::cin >> direction;//Õîðèçîíòàëåí èëè âåðòèêàëåí.
std::cin.ignore();
std::getline(std::cin, path);//Àäðåñè íà 3-òå èçîáðàæåíèÿ.
//Áóëåâè ïðîìåíëèâè, ÷ðåç êîèòî ïðîâåðÿâàìå äàëè ñúùåñòâóâàò äâåòå âúâåäåíè èçîáðàæåíèÿ â òåêóùàòà ñåñèÿ.
bool flag1 = false;
bool flag2 = false;
paths = findPath(path);//Îòäåëÿìå 3-òå àäðåñà.
std::string image1 = paths[2];
std::string image2 = paths[1];
std::string outimage = paths[0];
for (size_t i = 0; i < other.Formats().size(); i++)
{
if (other.Formats()[i]->getPath() == image1)
{
flag1 = true;
}
if (other.Formats()[i]->getPath() == image2)
{
flag2 = true;
}
}
//Àêî âúâåäåíèòå èçîáðàæåíèÿ ñà êîðåêòíè, ñúçäàâàìå êîëàæ.
if (flag1 == true && flag2 == true && countExistedImage(paths) == 2 && //Ñúùåñòâóâàùèòå èçîáðàæåíèÿ ñà äâå, çàùîòî òðåòîòî ãî ñúçäàâàìå.
(findFormat(image1) == findFormat(outimage)) && (findFormat(image2) == findFormat(outimage)))
{
/*Ñúçäàâà êîëàæ îò äâå èçîáðàæåíèÿ <image1> è <image2> (â åäèí è ñúù ôîðìàò è åäíà è ñúùà ðàçìåðíîñò),
íàëè÷íè â òåêóùàòà ñåñèÿ. Ðåçóëòàòúò ñå çàïèñâà â íîâî èçîáðàæåíèå <outimage>, êîåòî ñå äîáàâÿ â òåêóùàòà ñåñèÿ.*/
other.Formats().push_back(loadAccordingToFormat(outimage));
other.Formats().back()->collage(direction, image1, image2, outimage);
other.addTransformations("collage");
std::cout << "New collage \"" << outimage << "\" created!\n";
}
else std::cout << "Unable to make collage!\n";
}
void Editor::load()//Êîìàíäíà ôóíêöèÿ, ñúçäàâàùà ñåñèÿ è èçâúðøâàùà îñíîâíèòå ðåäàêöèè ïî èçîáðàæåíèÿòà.
{
std::string paths = {};//Ïðîìåíëèâà, ÷ðåç êîÿòî âúâåæäàìå àäðåñ/è íà èçîáðàæåíèå/ÿ.
std::cin.ignore();
std::getline(std::cin, paths);//Âúâåæäàìå àäðåñ/è íà èçîáðàæåíèå/ÿ.
std::vector<std::string> path = Editor::findPath(paths);//Îòäåëÿìå êîðåêòíèòå ôîðìàòè, çà äà ãè èìàìå åäèí ïî åäèí.
if (countExistedImage(path) != 0)//Àêî èìà ïîíå åäíà ñíèìêà, òî ñúçäàâàìå ñåñèÿ ñ óíèêàëåí èäåíòèôèêàöèîíåí íîìåð.
{
session.push_back(Session());
std::cout << "Session with ID: " << session.back().getId() << " started!\n";
for (int i = path.size() - 1; i >= 0; i--)
{
if (isCorrectFileFormat(path[i]) && read(path[i]))
{
session.back().Formats().push_back(loadAccordingToFormat(path[i]));//Äîáàâÿìå èçîáðàæåíèåòî ñïîðåä âèäà ìó.
session.back().Formats().back()->load(path[i]);//Çàðåæäà èíôîðìàöèÿ çà íåãî.
session.back().Transformations() = {};//Íÿìà íèêàêâè òðàíñôîðìàöèè âñå îùå.
std::cout << "Image " << path[i] << " added!\n";
}
else
{
std::cout << "Image " << path[i] << " is not added!\n";
}
}
do
{
do//Âúâåæäàìå êîìàíäà, êîÿòî òðÿáâà äà å âàëèäíà.
{
std::cout << ">";
std::cin >> command;
if (command == "session")
{
std::cin >> command;
if (command == "info") break;
}
} while (!isCommand(command));
if (command == "saveas")//Çàïèñâà íàïðàâåíèòå ïðîìåíè âúâ ôàéë, êàòî ïîçâîëÿâà íà ïîòðåáèòåëÿ äà óêàæå íåãîâèÿ ïúò.
{
commandSaveas(session[Session::getId() - 1], paths);
}
else if (command == "save")//Çàïèñâà íàïðàâåíèòå ïðîìåíè îáðàòíî â ñúùèÿ ôàéë, îò êîéòî ñà áèëè ïðî÷åòåíè äàííèòå.
{
commandSave(session[Session::getId() - 1]);
}
else if (command == "help")//Èçâåæäà êðàòêà èíôîðìàöèÿ çà ïîääúðæàíèòå îò ïðîãðàìàòà êîìàíäè.
{
help();
}
else if (command == "add")//Äîáàâÿ èçîáðàæåíèå êúì òåêóùàòà ñåñèÿ.
{
std::cin.ignore();
std::getline(std::cin, paths);
commandAdd(session[Session::getId() - 1], paths);
}
else if (command == "grayscale")//Ïðîìåíÿ ïèêñåëèòå äà ñà â ñèâ íþàíñ. Äåéñòâà ñàìî âúðõó öâåòíè èçîáðàæåíèÿ îò ".ppm" ôîðìàò.
{
commandGrayscale(session[Session::getId() - 1]);
}
else if (command == "monochrome")//Ïðîìåíÿ ïèêñåëèòå äà ñà ÷åðíè èëè áåëè. Äåéñòâà ñàìî âúðõó öâåòíè èçîáðàæåíèÿ îò ".ppm" ôîðìàò.
{
commandMonochrome(session[Session::getId() - 1]);
}
else if (command == "negative")//Öâåòîâî îáðúùàíå. Äåéñòâà âúðõó âñè÷êè ôîðìàòè è âñè÷êè èçîáðàæåíèÿ â ñåñèÿòà.
{
commandNegative(session[Session::getId() - 1]);
}
else if (command == "rotate")//Çàâúðòàíå íà èçîáðàæåíèÿòà â ñåñèÿòà íà 90° â çàâèñèìîñò îò çàäàäåíàòà ïîñîêà.
{
commandRotation(session[Session::getId() - 1]);
}
else if (command == "switch")//Ïðåâêëþ÷âà êúì ñåñèÿ ñ èäåíòèôèêàöèîíåí íîìåð <session>.
{
commandSwitchSession();
}
else if (command == "undo")//Ïðåìàõâà ïîñëåäíî íàïðàâåíàòà òðàíñôîðìàöèÿ â òåêóùàòà ñåñèÿ.
{
commandUndo(session[Session::getId() - 1]);
}
else if (command == "info")//Èçâåæäà èíôîðìàöèÿ çà ñåñèÿòà.
{
std::cout << session[Session::getId() - 1] << "\n";
}
else if (command == "collage")
{
commandCollage(session[Session::getId() - 1]);
}
} while (command != "close" && command != "exit");
if (command == "close")
{
std::cout << "Successfully closed!\n";
}
}
else
{
std::cout << "Cannot create session without correct images!\n";
}
}
void Editor::start()
{
do
{
do
{
std::cout << ">";
std::cin >> command;
} while (!isCommand(command));
if (command == "load")
{
load();
}
else if (command == "help")
{
help();
}
} while (command != "exit");
std::cout << "Exiting the program...\n";
//Èç÷èñòâàìå çàäåëåíàòà ïàìåò.
for (size_t i = 0; i < session.size(); i++)
{
for (size_t j = 0; j < session[i].Formats().size(); j++)
{
delete session[i].Formats()[j];
}
}
}