Autor: Tomáš Batěk
Váš program:
- z jednoho až n obrázků běžného formátu (BMP/SVG/RAW/TGA, ...) načte data a ty validně zobrazí v ASCII (odstíny šedi)
- ze souboru načte definovaný ASCII přechod umožňuje alespoň dvě jednoduché operace (zesvětlení/ztmavení obrázku, vymazání, konvoluce, negativ, ...)
- umožnuje "spuštění" animace v případě více načtených obrázků a triviální editaci animace na útovní framů (např. mazání framů, seřazení za sebou, ...)
- Program bude umět pracovat s minimálně jedním obrázkovým formátem.
Program bude mít jednoduché možnosti přehrávání animace (zastavit, spustit, zobrazit konkrétní frame, ...).
Kde lze využít polymorfismus? (doporučené)
- Nástroje pro manipulaci a jejich efekty, sady znaků, ...
- Formáty vstupu: BMP, SVG, RAW, ...
- Různé styly ASCII vykreslení
- Přehrávač: obrázek (jen zobrazí), sekvence (přehraje více obrázků)
- Uživatelské rozhraní: konzole, ncurses, SDL, OpenGL (různé varianty), ...
_.oo.
_.u[[/;:,. .odMMMMMM'
.o888UU[[[/;:-. .o@P^ MMM^
oN88888UU[[[/;::-. dP^
dNMMNN888UU[[[/;:--. .o@P^
,MMMMMMN888UU[[/;::-. o@^
NNMMMNN888UU[[[/~.o@P^
888888888UU[[[/o@^-..
oI8888UU[[[/o@P^:--..
.@^ YUU[[[/o@^;::---..
oMP ^/o@P^;:::---..
.dMMM .o@^ ^;::---...
dMMMMMMM@^` `^^^^
YMMMUP^
^^
Obrazovka aplikace může vypadat například takto (dolar značí vstup uživatele):
Enter command:
$ width 100
Maximum ASCII image width will now be 100 characters.
Enter command:
$ load
Found: example.jpeg
Loaded 1 image(s) in total.
Enter command:
$ convert
Converting example.jpeg...
Converted to /lorem/ipsum/converted/example.jpeg.ascii
V hlavním menu aplikace uživatel může nastavit umístění složky, odkud se budou načítat obrázky. To je jediná nutná informace pro konverzi obrázků. Volitelně poté uživatel může specifikovat, zda chce vzhled ASCII obrázku přizpůsobit tmavému terminálu, výchozí nastavení je totiž pro světlý. Dále také může načíst ze souboru vlastní ASCII přechod, pokud nechce použít výchozí - stačí specifikovat cestu k souboru, ze kterého program přečte první řádku. Všechna tato nastavení budou mít vliv na všechny podprogramy a zůstanou uložena po celou dobu běhu aplikace.
folderse dotáže na umístění složky, odkud se obrázky budou načítatinvert truenastaví inverzi obrázků, doporučeno pro tmavý terminálinvert falsezruší inverzi obrázků (výchozí nastavení), doporučeno pro světlý terminálcustomse dotáže na umístění souboru, odkud má program načíst vlastní ASCII přechodconverterspustí podprogram pro koverzi obrázků do ASCII-artuanimatorspustí podprogram, který zobrazí animaci z několika obrázků v ASCII-artueditorspustí podprogram pro jednoduchou editaci ASCII-art obrázkůhelpzobrazí nápovědu (funguje v každém podprogramu)quitukončí program
Pokud uživatel specifikoval složku, odkud má program načítat obrázky, může si je nyní nechat načíst, program poté zobrazí, které obrázky se mu podařilo načíst. Volitelně může uživatel specifikovat maximální šířku (ve znacích) pro konvertované obrázky, či si nechat maximální šířku nastavit podle šířky okna terminálu. Pokud uživatel maximální šířku nezadá, nebo ji nastaví na 0, tak konvertované obrázky zachovají svojí původní velikost (jeden pixel je reprezentován dvěma znaky). Nyní si uživatel může nechat načtené obrázky překonvertovat. Obrázky se budou ukládat do složky "converted/", která se vytvoří v původně zadané složce. Pokud chce uživatel resetovat všechna nastavení, může tak v tomto podprogramu učinit, resetuje tím však i nastavení z hlavního menu aplikace. Jakmile uživatel tento podprogram opustí, nastavení učiněná v tomto podprogramu se zapomenou.
Pokud formát obrázku podporuje průhlednost, tak budou všechny zcela průhledné pixely nastaveny na bílou nebo černou podle toho, jak je nastavena inverze.
howtozobrazí nápovědu, jak konvertovat obrázkyloadnačte obrázky ze zadané složkymatchnastaví maximální šířku (ve znacích) pro konvertované obrázky podle šířky termináluwidth <num>nastaví maximální šířku (ve znacích) pro konvertované obrázky, 0 ponechá původní velikosti (výchozí nastavení)resetobnoví všechna nastevní do výchozí hodnotyconvertvytvoří v zadané složce podsložku s konvertovanými obrázkybackse vrátí zpět do menu programu
Aby mohl uživatel pracovat s tímto podprogramem, musí nejdříve alespoň 1 obrázek pomocí konverteru vytvořit. Poté uživatel může obrázky načíst a program řekne, které obrázky se mu podařilo načíst. Volitelně může uživatel nastavit počet snímku za sekundu při zobrazovaní animace (výchozí nastavení je 30 FPS), dále může volitelně prohazovat pořadí snímků. Pokud chce zjistit, který snímek ja na kterém místě, může si to nechat zobrazit. Poté si může nechat animaci zobrazit. Jakmile uživatel tento podprogram opustí, nastavení učiněná v tomto podprogramu se zapomenou.
howtozobrazí nápovědu, jak zobrazovat animaciloadnačte obrázky ze složky converted/positionszobrazí současnou pozici obrázků v animaciswap <num> <num>prohodí pořadí dvou zadaných obrázků v animacifps <num>nastaví framerate animaceshowzobrazí animacibackse vrátí zpět do menu programu
Aby mohl uživatel pracovat s tímto podprogramem, musí nejdříve alespoň 1 obrázek pomocí konverteru vytvořit. Poté si může nechat vypsat, které obrázky může načíst. Jeden z nich si uživatel vybere a nechá si ho načíst. Tento obrázek si může nechat zobrazit a upravovat, konkrétně má možnost obrázek zesvětlit, ztmavit a udělat negativ.
howtozobrazí nápovědu, jak upravovat obrázekimageszobrazí obrázky, které jdou načístload <filename>načte daný obrázekshowzobrazí obrázekbrightenobrázek zesvětlídarkenobrázek ztmavínegativeudělá z obrázku negativbackse vrátí zpět do menu programu
Polymorfismus využívám u různých formátů obrázků. Mám abstraktní třídu Image, ze které
dědí ImageJPG a ImagePNG, které se každé převádí do RGB trochu jinak. Program má
jen skupinu obrázků typu Image a na nich volá konverzi.
Polymorfní volání je v třídě ConverterController, která obsahuje
vector načtených obrázků jako unique pointery. Command convert při konverzi
neřeší, jakého je obrázek typu, protože u každého obrázku zavolá abstraktní metodu
extract.
Kdybych se rozhodl přidat podporu pro další typy obrázků, vytvořil bych jen
dalšího potomka třídy Image a definoval mu, jak se má převést do RGB.