Octave - szybkie klejenie obrazków cz. 1
Wstęp
Z racji istniejącego jeszcze na DobrychProgramach ograniczenia na liczbę obrazków w jednym wpisie na blogu, kilkukrotnie już musiałem sklejać kilka obrazków w jeden. Ostatnim razem było to aż 5 obrazków. Na szczęście nie musiałem stosować brutalnej metody, która przychodzi do głowy jako pierwsza: otworzyć w GIMP-ie pierwszy obrazek, rozciągnąć płótno, dodać drugi obrazek i tak do skutku. Szybko i sprawnie zrobiłem to w Octave'ie.GNU Octave to jedno z moich podstawowych narzędzi pracy, obok Opery, Kile i Geany. Jest to wolny pakiet numeryczny, podobnie jak opisany przez arlida Scilab. To, co arlid dotąd napisał o obsłudze Scilaba (cz. 1 i cz. 2 ), przekłada się w całości na Octave'a.
Do dzieła
Przyjmijmy na wstępie, że mamy do sklejenia dwa obrazki o takiej samej szerokości i wysokości (np. zrzuty z okna jakiegoś kreatora). Przyjmijmy też, że pierwszy obrazek nazwaliśmy "a.png", a drugi "b.png" (nazwy im krótsze, tym wygodniej). Po uruchomieniu Octave'a, należy oczywiście przejść do katalogu, w którym znajdują się owe obrazki, u mnie jest to Pulpit, a więc:
octave-3.2.4:1> cd ~/Pulpit
Teraz wczytujemy pliki do zmiennych (znów, nazwy im krótsze, tym wygodniej):
octave-3.2.4:2> a=imread('a.png'); octave-3.2.4:3> b=imread('b.png');
Uwaga! Średniki na końcach linii są istotne - bez nich wyświetli się cała zawartość podanych zmiennych. Zmienne te są macierzami (tu: trójwymiarowymi tablicami liczb od 0 do 255) i to te macierze zostaną wypisane (nie zostaną wyświetlone obrazki). Teraz można przejść do klejenia. Utworzymy dwie nowe zmienne (c i d), w których znajdą się sklejone obrazki. Zmienna c będzie macierzą o wysokości równej sumie wysokości macierzy a i b, bo skleimy w niej a.png nad b.png. Zmienna d będzie macierzą o szerokości równej sumie szerokości macierzy a i b, bo skleimy w niej a.png na lewo od b.png.
octave-3.2.4:4> c=[a;b]; octave-3.2.4:5> d=[a b];
Tu znów musimy pamiętać o średnikach na końcach, aby uniknąć zasypania ekranu mnóstwem liczb. Bardziej istotne jest jednak to, co dzieje się między znakiem równości a średnikiem: "[" oznacza początek wprowadzania macierzy, "]" oznacza koniec wprowadzania macierzy, do macierzy c i do macierzy d wstawiamy wszystkie elementy macierzy a i b (całe obrazki), więc wystarczy podanie nazw zmiennych a i b, średnik rozdzielający a i b w pierwszym klejeniu oznacza koniec wiersza macierzy, czyli że b idzie pod a, czyli to, o co nam chodziło, spacja rozdzielająca a i b w drugim klejeniu oznacza następny element w wierszu, czyli że b jest obok a, czyli znów to, jak miało być. Zamiast spacji może być też przecinek - bez różnicy.
Efekt możemy podejrzeć:
octave-3.2.4:6> imshow(c) octave-3.2.4:7> imshow(d)
Tutaj średnik na końcu jest nieistotny.
Jeśli mamy więcej obrazków, postępujemy podobnie:
c=[a1;a2;a3;a4];
w przypadku kolumny obrazków i
c=[a1 a2 a3 a4];
w przypadku poziomego ciągu. Można też połączyć obie sprawy: a1 i a2 obok siebie u góry, a3 i a4 pod nimi, też obok siebie:
c=[a1 a2;a3 a4];
Przyszedł czas na zapis:
octave-3.2.4:8> imwrite(c,'c.png')
Macierz c zapisujemy do pliku c.png. Octave po rozszerzeniu domyśla się jak ma tę macierz wykorzystać, więc żadne inne opcje nie są konieczne (choć istnieją).
Całą operację można jeszcze zapisać skrótowo w jednej linii:
imwrite([imread('a.png');imread('b.png')],'c.png')
oraz uprościć jeszcze bardziej, wywołując Octave'a z wiersza poleceń z podaną wyżej komendą jako parametrem:
q@q-laptop:~$ octave-3.2.4 -q --eval 'cd ~/Pulpit/; imwrite([imread("a.png");imread("b.png")],"c.png")'
"octave-3.2.4" - tym poleceniem odpalam u siebie Octave'a, polecenie to zależy od systemu operacyjnego, "‑q" jest tu po to, żeby Octave nie zanudzał nas informacjami powitalnymi, "-‑eval" mówi, że jest kod do wykonania (więcej parametrów nie ma, więc po wykonaniu kodu, Octave się zamknie), średnik w kodzie separuj poszczególne polecenia (tu mógłby też być przecinek). W samym kodzie zmieniłem cudzysłowy pojedyncze na podwójne - Octave'owi nie robi różnicy który cudzysłów dostanie, ale że całe polecenie ubrane jest w cudzysłów, bez tej zmiany by się pogryzło.
Komplikator
A co będzie, jak obrazki sklejane obok siebie będą różnej wysokości, albo sklejane jeden pod drugim będą różnej szerokości? O tym w części drugiej.
PS. Inspiracją do takiego wykorzystania Octave'a był wpis Saskatchewana na jego blogu w My Opera.