Obrót obrazka rastrowego

0

Zastanawiam się jak można obrócić obrazek rastrowy.
Mam JPanel na którym wyświetlony w pewnym miejscu jest obrazek rastrowy.
Jeśli chodzi o jego translację, czy skalowanie, to raczej dam radę. Żeby dostać się do każdego piksela wystarczy dwa razy użyć pętli for od jednego wierzchołka do drugiego.
Ale co z obrotem? Wtedy obrazek już nie jest prostokątem, tylko równoległobokiem i nie da się tak łatwo przejść po jego wszystkich pikselach.
A może po prostu trzeba jako obrazek traktować cały ekran malowania i tło tez od nowa malować? Choć to wydaje mi się trochę bez sensu :P
Mam nadzieje, że rozumiecie o co mi chodzi. Jak nie, to napiszcie co słabo wytłuamczyłem, to postaram się opisać to konkretniej :P
Z góry dzięki za pomoc.

0

Żeby było jaśniej :P
Mam zrobic program, który wczytany obrazek rastrowy może przeskalować, obrócić i przesunąć oraz wykonać dowolne złożenie tych operacji.
Do skalowania mam uzyć interpolacji dwuliniowej, więc do tych operacji muszę dla każdego poksela w obrazie wynikowym wyznaczyć odpowiadający mu piksel w obrazie startowym - przy użyciu macierzy odwrotnej do tej, która przekształcamy obraz.
Pierwsze pytanie: żeby wiedzieć gdzie znajduje się wynikowy obraz, najpierw musimy przemnożyć wierzchołki obrazu startowego przez macierz operacji, aby wiedzieć gdzie rozciąga się obraz końcowy?
Drugie pytanie: jeśli obraz wynikowy nie jest prostopadły/równoległy do osi, tylko przekrzywiony, to jak można przejść po ejgo wszystkich pikselach? Bo dwie pętle for w tym wypadku raczej odpadają...

0

http://download.oracle.com/javase/tutorial/2d/images/index.html

Wszystko jest już zaimplementowane. Masz nawet dostęp do dowolnych przekształceń afinicznych.

Poza tym jest BufferedImage.getWritableTile().setPixels(...)

0

Wszystkie macierze i przekształcenia muszę miec napisane samodzielnie.
Podstawy klasy BufferedImage znam ;)

Weźmy taki przykład, że dostaję jakąś macierz - nie wiem co to za przekształcenie. I co po kolei robię z obrazkiem startowym?

  1. Najpierw wyliczam gdzie znajduje się obraz wynikowy? Czyli przez tą macierz mnożę wierzchołki obrazka. Tak?
  2. Wiem gdzie jest obraz wynikowy. Muszę go teraz stworzyć. Dla każdego piksela z tej przestrzeni muszę znaleźć odpowiadający mu piksel z obrazu startowego. Wykorzystuję tu polaryzację dwuliniową. Problem w tym jak przejść po wszystkich pikselach obrazu wynikowego (czyli od wierzchołka A do wierzchołka B i w tym od wierzchołka A do wierzchołka C, jeśli obrazek jest prostokątem ABCD), żeby ustawić im odpowiednie kolory? Zwłaszcza jeśli obraz jest przekrzywiony, czyli przejście dwoma pętlami for odpada.

Jak już napisałem wyżej - znam metody pobierania piksela, ustawiania koloru piksela itp.
Z góry dzięki za pomoc.

0

"polaryzację dwuliniową"
Chyba interpolację.

Wydaje mi się że obrazek jest zawsze prostokątem. Przy rysowaniu robisz te dwie pętle i rysujesz po kolejnym prostokątnym obrazku z uwzględnieniem transformacji.

W przekształceniu afinicznym mamy współrzędne jednorodne uwzględniające skalowania, obroty, rotacje itp, a więc po prostu pozycję każdego piksela wejściowego mnożymy przez macierz i dostajemy miejsce gdzie go powinniśmy namalować.

Nikt ci też nie broni czytać źródeł JDK. Ja pewnie bym tak zrobił.

0
donkey7 napisał(a)

"polaryzację dwuliniową"
Chyba interpolację.

Oczywiście, moja pomyłka. Jestem świezakiem w tym temacie i stąd ta pomyłka :P

Wydaje mi się że obrazek jest zawsze prostokątem. Przy rysowaniu robisz te dwie pętle i rysujesz po kolejnym prostokątnym obrazku z uwzględnieniem transformacji.

W przekształceniu afinicznym mamy współrzędne jednorodne uwzględniające skalowania, obroty, rotacje itp, a więc po prostu pozycję każdego piksela wejściowego mnożymy przez macierz i dostajemy miejsce gdzie go powinniśmy namalować.

No tak, ale jak obrazek powiększamy to musimy dla każdego piksela wyjściowego, szukać piksel wejściowy. Czyli musimy iść po każdym pikselu obrazu wyjściowego. A co jeśli był on jednocześnie obrócony?

0

Obrazki są tylko prostokątne.

Jeśli zrobiłeś jakąś transformację za pomocą macierzy to możesz ją odwrócić (ale zwykle z utratą części informacji) poprzez znalezienie odwrotności dla tamtej macierzy.

Jaki ty masz problem z tymi obrotami? Obrócony obrazek jest dalej prostokątny, niektóre piksele mogą być obcięte, inne wypełnione domyślną wartością, choćbyś nie wiem co robił nie zrobisz obrazka który nie jest prostokątny.

PS:
Jeśli chcesz robić milion transformacji w ciągu to nie transformuj cały czas na bieżąco, tylko działaj na macierzy przekształceń i dopiero na końcu dokonaj przekształcenia.

0

Czyli po obrocie mam mieć obrazek prostokątny, który ma w sobie obrócony obrazek wejściowy, a te zostające trójkąty mam wypełnić tłem?
I to jest poprawne rozwiązanie?
Bo jeśli tak, to problem mam juz rozwiązany :P

0

Jeśli chodzi o PS, to wiem.
Najpierw mnożę te wszystkie macierze, a potem dopiero przekształcam obrazek przez jedną macierz :P

0

No ja na razie nie znam sposobu żeby zrobić nieprostokątny obrazek. Wypełniaj tłem, albo co najwyżej ustaw przezroczystość w pustych miejscach. W każdym programie czy systemie obrazki są kwadratowe, nie widzę powodu żeby w Javie kombinować inaczej.

0

W takim razie bardzo dziękuję za pomoc :) Myślę, że z sama implementacją tych pomysłów już sobie poradzę :)

0

Po obrocie obrazka jego krawędzie nie są gładkie. Są takie postrzępione.
Tutaj przykład: http://www.fotosik.pl/pokaz_obrazek/93f03afad599bdb5.html
Da się z tym coś zrobić? Czy po prostu tak juz zostawić?

1 użytkowników online, w tym zalogowanych: 0, gości: 1