Czy jest jakiś prosty sposób (gotowa klasa w javie), na obsługę kliknięcia nieregularnego fragmentu grafiki? Przykładowo, mam mapę Europy i chciałbym by zadziało się coś konkretnego po kliknięciu w obszar Polski - muszę sobie podzielić obszar na małe prostokąty (inne regularne kształty) i cierpliwie to zaimplementować, czy jest jakiś szybszy sposób?
A nie da się zrobić jakiegoś obejścia typu
onClick pobiera kolor rgb z klikniętego pixela i coś dalej z tym robi
np.
kolor czech = rgb(0,0,255)
kolor bułgarii = rgb(0,0,250)
Oba są niebieskie, a dla człowieka mała różnica :P
Jedynie musiałbyś przerobić ten obrazek ( w sumie wypełnienie obszaru powinno dać rade ) :P
Bazowanie na kolorze widocznym na ekranie to słabe rozwiązanie – jeśli grafika używa antialiasingu, istnieje prawdopodobieństwo pobrania koloru z obrzeża, który używany jest do malowania zupełnie innego państwa. Poza tym, każde państwo musi w takim przypadku używać innego koloru, co nie ma miejsca na tej grafice i co stanowi pewne ograniczenie.
Rozwiązanie jest proste – druga bitmapa, niewidzialna (przechowywana wyłacznie w pamięci), bez antialiasingu. Ustawiasz białe tło dla pustych miejsc oraz przerw pomiędzy obszarami państw. Każde państwo malujesz konkretnym kolorem – pierwsze kolorem 0,0,0
, drugie kolorem 0,0,1
itd. W ten sposób uzyskasz 24-bitową pulę kombinacji, a same składowe koloru konkretnego państwa możesz bezpośrednio przekonwertować na liczbowy indeks (od 0
dla koloru 0,0,0
do 16777215
dla koloru 255,255,255
). Z tym że biały kolor zarezerwowany jest dla pustej przestrzeni.
Po kliknięciu na mapkę, pobierasz współrzędne kursora, następnie pobierasz kolor znajdujący się w tym miejscu w pomocniczej bitmapie, składowe koloru konwertujesz na liczbowy indeks. Na koniec ten indeks możesz użyć do wydobycia obiektu z listy wszystkich widocznych na właściwym obrazku państw, w celu np. odczytania nazwy państwa i innych danych, które potrzebujesz.
Najciekawiej z punktu widzenia algorytmicznego będzie przetransformować ten obrazek na listę wielokątów (polygonów) i sprawdzać, który znajduje się pod myszą w momencie kliknięcia ;-)
Poprawiłem mapę, bo tę kolorową wrzuciłem dla przykładu, w rzeczywistości korzystam z tej w załączniku. Zrobię jak radzisz, @furious programming, muszę tylko zmienić moje pliki graficzne na obiekty klasy BufferedImage, bo póki co są Image i zdaje się że nie mam zbyt dużego pola manewru jeśli chodzi o pobieranie kolorów pikseli.
- znajdź w googlu mapę świata czy czego tam szukasz
- uruchom painta czy cokolwiek innego do grafiki
- pokoloruj każde państwo na inny kolor
- zapisz pokolorowana mapa jako nowy obrazek
- wyświetlaj obrazek niepokolorowanej mapy w swojej aplikacji
- jak ktoś gdzieś kliknie to wykonaj test na pokolorowanej mapie w zależności od klikniętego koloru możesz uzyskać kraj
- kliknięty obszar przenieś na grafikę...
przy okazji możesz nadać temu dowolny kolor...
może średnio to opisałem... ale jeśli chcesz zrobić program sprawdzający w który kraj kliknięto to jest to rozwiązanie
przy okazji grafiki można skalować itp.
przy okazji polska ma kolor czerwony niemce niebieski a wungry zielony
if(MapaKolorow[X-myszki][Y-myszki]==0xff0000)return Polska;
if(mapaKolorow[...][...]...)return anything else;
ofc. to dałoby się zrobić jeszcze szybciej ale w Java nie pracuję już od ... 4/5 lat...
więc nie chcę się "rozpędzać" aby zaraz nie podać ci czegoś czego w javie nie ma...
ale na 100% jestem pewien że masz tam coś na wzór "GetPixel(x,y,);" lub coś podobnego
@Jarek Szulc: spróbowałem obróbki – w załączniku podaję 24-bitową bitmapę z białym tłem i czarnymi obszarami państw. Teraz wystarczy pomalować fragmenty państw na konkretne kolory i tyle – można podpiąć obraz do programu.
Trzeba tylko sprawdzić, czy wypełnianie nie pomaluje kilku obszarów (czy obszary nie stykają się w taki sposób, że flood fill wypełni za dużo). To można bardzo szybko sprawdzić w Paint – wybrać np. czerwony kolor, wypełnić, sprawdzić, cofnąć, wypełnić kolejny, sprawdzić, cofnąć itd.
Oczywiście jeśli chcesz zrobić to w ten sposób, o którym napisałem. Sam tak bym to zrobił, jednak inny sposób może okazać się lepszy. ;)