• Nie Znaleziono Wyników

AWT cd..Java

N/A
N/A
Protected

Academic year: 2021

Share "AWT cd..Java"

Copied!
44
0
0

Pełen tekst

(1)

Uniwersytet Łódzki

Wydział Matematyki i Informatyki, Katedra Analizy Nieliniowej

AWT cd..

Java

Wykład 4

(2)

Plan wykładu

 Manager rozkładu

 Zdarzenia w AWT

 Grafika 2D w AWT

 Omówienie przykładowych pakietów

 Wyjątki

(3)

Layout Manager

Menadżer rozkładu przypisany jest do każdego kontenera

Ustala pozycję i wielkość dla komponentu w oknie

Pomocny przy organizowaniu zawartości okna, które zmienia rozmiar lub jest wyświetlane na różnych systemach

Prosty dla prostych rozkładów, jednakże bardzo ciężko jest projektować programy zawierające wiele elementów w pojedynczym menadżerze rozkładu.

W celu zarządzania złożonymi rozkładami należy:

Używać zagnieżdżonych kontenerów – każdy z własnym layout manager

Używać niewidzialne komponenty oraz opcji menadżerów rozkładów

Pisać własne layout manager

Wyłączyć niektóre layout manager i zarządzać komponentami manualnie.

Wszystkie Layout Manager implementują Layout Manager Interface

(4)

FlowLayout Manager

Domyśłny dla Panel, JPanel, Applet

Zachowanie:

Zmienianie rozmiaru komponentów do ich najlepszego rozmiaru

Umieszczanie komponentów w rzędzie od lewej do prawej od góry do dołu

Wiersze są wyśrodkowane domyślnie

Konstruktor

FlowLayout() – wyśorodkowuje każdy wiersz i utrzymuje 5 px. odstępy pomiędzy komponentami i wierszami

FlowLayout(int alignment) – utrzymuje 5px odstępy w wierszu, ale zmienia wyrównanie w wierszach: FlowLayout.LEFT, FlowLayout.RIGHT,

FlowLayout.CENTER

FlowLayout(int alignment, int hGap, int vGap) – pozwala specyfikować

wyrównanie w wierszach jak i również odstęp poziomy i poionowy pomiędzy komponentami w [px].

(5)

BorderLayout Manager

 Każdy z komponentów może być włożony do kontenera w jedną z lokalizacji:

 North

 South

 East

 West

(6)

GridLayout

Zachowanie

Podział okna na równej wielkości prostokąty bazujące na liczbie wierszy i kolumn podanych jako argument.

Komponenty umieszczane są w komórkach w kolejności od lewej do prawej od góry do dołu w porządku dodawania do kontenera

posiadającego ten rozkład

Ignoruje preferowany rozmiar

komponentu. Każdy komponent jest skalowany i dopasowywany do

komórki

Zbyt mała liczba komponentów powoduje pozostawienie wolnego miejsca w postaci białych prostokątów

Zbyt wiele komponentów powoduje nieplanowane dodanie nowych kolumn

GridLayout()

Tworzy pojedynczy wiersz z jedną kolumną zaalokowana dla każdego komponentu.

GridLayout(int rows, int cols)

Dzieli okno zgodnie z podaną liczbą kolumn oraz wierszy

Liczba kolumn lub wierszy może być zero

GridLayout(int rows, int cols, int hGap, int vGap)

Pozwala na wyspecyfikowanie

przestrzeni pomiędzy poszczególnymi komórkami

(7)

GridBagLayout

Zachowanie

Dzieli okno na komórki, w których komponenty mogą mieć różne rozmiary

Dużo wygodniejsze i bardziej elastyczne niż inne standardowe menadżerzy rozkładów, jednakże dużo trudniejsze w użyciu:

Każdy komponent zarządzany przez GridBagLayout skojarzony jest z GridBagConstraints, który definiowany jest przez:

jak komponent jest rozkładany w wyświetlanym obszarze

w której komórce komponent się rozpoczyna i kończy

jak komponent rozciąga się, kiedy przestrzeń się zwiększa

wyrównanie w komórkach

Java 5 wprowadziła SpringLayout, który jest podobny jednakże bardziej

(8)

Użycie GridBagLayout

Ustawienie rozkładu i zachowanie go w zmiennej referencyjnej:

GridBagLayout layout = new GridBagLayout();

setLayout(layout);

Przygotowanie objektu GridBagConstraints

GridBagConstraints constraints = new GridBagConstraints();

Ustawienie GridBagConstraints dla jednego komponentu:

constraints.gridx = x1;

constraints.gridy = y1;

constraints.gridwidth = width1;

constraints.gridheight = height1;

Dodanie 1 komponentu do okna uwzględniając jego GridBagConstraints

add(component1, constraints);

Powtórzenie kroków dla pozostałych komponentów

(9)

Pola w GridBagConstrains

 gridx, gridy

Specyfikuje górny lewy róg komponentu

Najwyższa komórka jest lokowana w (gridx, gridy)=(0,0)

 Ustawienie GridBagConstraints.RELATIVE w sytuacji autoinkrementacji kolumn wierszy

 GridBagConstraints constraints = new GridBagConstraints();

 constraints.gridx = GridBagConstraints.RELATIVE;

 container.add(new Button(„1"), constraints);

(10)

Wyłączenie menadżera rozkładu

 Zachowanie

 Jeśli rozkład jest ustawiony jako null, wówczas komponenty muszą być

rozmieszczane i skalowane ręcznie.

 Pozycjonowanie i skalowanie komponentów:

component.setSize(width, height)

component.setLocation(left, top)

lub component.setBounds(left, top,width, height)

(11)

Wskazówki przy używaniu Layout Manager

Używaj zagnieżdżonych kontenerów

Nie próbuje dopasować na siłę swojego złożonego rozkładu elementów do jednego menadżera rozkładu. Staraj się podzielić projekt w sekcje.

Skorzystaj z Panel jako sekcji wykorzystując do tego jego własny layout manager

Wyłącz menadżera rozkładu dla niektórych kontenerów, w których nie ma zbyt wielu elementów i można zarządzać nimi ręcznie.

Dopasuj puste miejsce wokół komponentów:

Po przez zmianę rozmiaru przestrzeni przydzielonej standardowo przez menadżera rozkładu

Użyj Płótna lub Box (w Swing) jako niewidzialnych elementów

oddzielających komponenty

(12)

Menadżer rozkładu - podsumowanie

Inne rozkłady: BoxLayout, CardLayout

Domyślne layout managers

Dla apletu i panelu: FlowLayout

Dla okienka i dialog BorderLayout

Menadżer rozkładu respektuje preferowany rozmiar komponentu w różny sposób

GridBagLayout jest najbardziej skomplikowanym rozkładem ale jednocześnie najbardziej funkcjoanlnym/elastycznym

GridBagConstraints wykorzstywany w przypadku konieczności wyspecifikowania rozkładu dla każdego komponentu

Złożone rozkłady mogą być uproszczone przez zastosowanie zagnieżdżonych kontenerów

W AWT jako element odzielający wykorzystuje się Canavas a w Swing Box

(13)

Zdarzenia (Events)

Cel: potrzeba dowiedzenia się o czymś, co wydarzyło się poza obiektem.

Zdarzenie (Event) – nośnik informacji o zajściu określonej sytuacji

Przykład 1: użytkownik wciska przycisk na ekranie

Przykład 2: Przyjście pewnej porcji informacji na port serwera (aplikacja web chat)

Obiekt, w którym pojawiło się zdarzenie – generator zdarzeń (event generator). Np. przycisk na ekranie.

Obiekt, który wykona pewne zadanie po otrzymaniu zdarzenia –

event handler. Dla wybranego zdarzenia może być wiele event

handlers, które mogą wykonać różne zadania.

(14)

Mechanizm obsługi zdarzeń

 Archaiczne podejście do obsługi zdarzeń: polling.

Przebieganie stanu obiektów w pętli. Podejście absorbujące dużą ilość zasobów (olbrzymia pętla).

 Generator zdarzeń udostępnia usługę rejestracji –

pamięta, do których event handlers powinien przekazać zdarzenia

 Rejestracja event handlers u generatora zdarzeń

 Wykorzystanie diagramów MSC do modelowania systemów sterowanych zdarzeniami.

 Message Driven Application - Zastosowania w

systemach rozproszonych.

(15)

Mechanizm obsługi zdarzeń w Javie

Generatory zdarzeń

udostępnia JVM. Programista implementuje wyłączenie

zachowanie event handlers – tzw. nasłuchiwaczy (listeners) .

W razie wyszukanych potrzeb programista może jednak

zaimplementować własne generatory zdarzeń.

Po implementacji event

handlers należy zarejestrować

Przykład: Java Button

Generuje zdarzenia ActionEvents

Nasłuchiwacz rejestruje się u Java Button po przez wywołanie metody

addActionListner z parametrem

wskazującym kto będzie nasłuchiwał.

Metoda ta generuje wiadomość addActionListener

Java Button pamięta, kto się u niego zarejestrował (automatyczny mechanizm dostarczany przez JVM)

W momencie wystąpienia zdarzenia w Java Button, Java Button generuje wiadomość actionPerformed, do każdego z

zarjestrowanych nasłuchiwaczy.

Listner powinien mieć zaimplementowaną metodę actionPerformed, która zostanie

(16)

Mechanizm obsługi zdarzeń diagram MSC

Button Button = new Button(„Klik!");

Button.addActionListener(new Nasluchiwacz());

// rejestracja

class Nasluchiwacz implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println(„nasinieto przycisk");

// wykonanie zadania }

}

(17)

Przykład 2 – hierarchia generowania zdarzeń przez komponenty.

public boolean handleEvent(Event e)

e – parametr z referencją na zdarzenie, które powstało

Ważna jest wartość zawracana przez handleEvent. Informuje JVM, czy zdarzenie zostało w pełni obsłużone

Zdarzenie propaguje w górę

drzewa, do momentu, kiedy nie

zostanie poprawnie obsłużone

(18)

Metody pomocnicze do obsługi zdarzeń

W przypadku konieczności obsłużenia wybranych zdarzeń można skorzystać z funkcji pomocniczych

Metoda pomocnicza zwraca wartość false w przypadku, gdy zdarzenie nie zostanie w pełni obsłużone

Przykład 3

action(Event evt, Object what)

gotFocus(Event evt, Object what)

lostFocus(Event evt, Object what)

mouseEnter(Event evt, int x, int y)

mouseExit(Event evt, int x, int y)

mouseMove(Event evt, int x, int y)

mouseUp(Event evt, int x, int y)

mouseDown(Event evt, int x, int y)

mouseDrag(Event evt, int x, int y)

keyDown(Event evt, int key)

keyUp(Event evt, int key)

(19)

Przykładowy zestaw zdarzeń

Window Events

WINDOW_DESTROY (201)

WINDOW_EXPOSE (202)

WINDOW_ICONIFY (203)

WINDOW_DEICONIFY (204)

WINDOW_MOVED (205)

Keyboard Events

KEY_PRESS (401)

KEY_RELEASE (402)

KEY_ACTION (403)

KEY_ACTION_RELEASE

Mous Events

MOUSE_DOWN 501

MOUSE_UP 502

MOUSE_MOVE 503

MOUSE_ENTER 504

MOUSE_EXIT 505

MOUSE_DRAG

Różne zdarzenia

ACTION_EVENT 1001

Przykłady zdarzeń

(20)

Klasa Event

long when Chwila, w które zdarzenie wystąpiło.

int id Typ zdarzenia (patrz następny slajd)

int x Współrzędna X określająca miejsce, w którym zdarzenie się pojawiło w odniesieniu do komponentu, który jest aktualnie przetwarzany. Początkowa

wartość x jest to górny lewy róg.

int y Współrzędna X określająca miejsce, w którym zdarzenie się pojawiło w odniesieniu do komponentu, który jest aktualnie przetwarzany. Początkowa

wartość x jest to górny lewy róg.

int key Dla zdarzeń pochodzących z klawiatury. Jest to kod wciśniętego klawisza. Przeważnie jest to wartość zapisana w postaci unicode.

int modifiers arytmetyczna reprezentacja wartości SHIFT_MASK, CTRL_MASK, META_MASK, and ALT_MASK. Wartość zostaje zmieniona odpowiednio dla zmiany stanu klawiszy shift, control, meta, alt.

int clickCount Liczba kliknięć myszy. Pole te jest istotne wyłącznie przy zdarzeniu MOUSE_DOWN.

Object arg Zależny od zdarzenia argument. Dla obiektów Button, object jest ciągiem znaków, który zawiera jego etykietę.

(21)

Przykład 1. Aplikacja obsługująca

zdarzenia

(22)

Java 2D

Java 2D API umożliwia pracę z obrazami, tekstem i grafiką jako rozszerzenie AWT

Zakres dostarczanej funkcjonalności:

Ujednolicony model renderingu dla różnych rodzajów wyświetlaczy i drukarek (user space)

Duży zbiór różnych podstawowych kształtów geometrycznych takich jak:

prostokąty, krzywe, elipsy jak i również mechanizm do renderowania dowolnych kształtów.

Mechanizm dla wykrywania kilknięć na kształtach, tekście i obrazkach

Sterowanie sposobem rednerowania zachodzących na siebie obiektów

Zarządzanie kolorami

Wsparcie dla wydruków złożonych dokumentów

Sterowanie jakością renderowanych obiektów (anty-aliasing)

(23)

Układ współrzędnych

 Java 2D rozróżnia dwa układy współrzędnych

Przestrzeń użytkownika (user space) – miejsce, w którym obiekty są

specyfikowane

Przestrzeń urządzeń (device space) – układ

współrzędnych związanych z urządzeniem, na którym ma zostać wyświetlona wyspecyfikowana grafika

(0,0) x

y

Typem dla x i y jest integer. Wspierany jest również float i double.

(24)

Java 2D rendering

Java udostępnia wspólny

mechanizm modelowania grafiki dla różnych urządzeń

W przypadku konieczności

wyświetlenia/wykreślenia danego kształtu wywoływane są

automatycznie metody paint() lub update() z kontekstem

graficznym Graphics. Metody te zawiera każdy obiekt

rozszerzający Component.

Pakiet java.awt.Graphics2D oferuje następujące możliwości:

rysowanie podstawowych kształtów geometrycznych z

uwzględnieniem krawędzi (metody draw)

wypełnianie kształtów kolorem lub określonym wzorem (metody fill)

rysowanie tekstu (drawString).

Określenie czcionki wskazuje w jaki sposób ma być danych tekst przekształcony w obiekt graficzny, który jest wypełniony kolorem lub wzorem

rysowanie obrazków (metoda drawImage)

(25)

Metody wykorzystywane przy rysowaniu w Java 2D

Metody do rysowania można podzielić na dwie grupy

Metody definiujące kształt (metody draw, fill)

Metody określające w jaki sposób ten kształt ma być narysowany – zmiana atrybutów kontekstu (Graphics)

W celu użycia dodatkowych funkcjonalności oferowanych przez Java 2D należy rzutować obiekt typu Graphics na

Graphics2D

Możliwość modyfikacji atrybutów związanych z określonym

kontekstem

modyfikacja szerokości linii/krawędzi rysunku

zmiana sposobu łączenia linii/krawędzi

przekształcanie rysunku:

obracanie skalowanie lub przycinanie

określanie koloru i wzoru wypełnienia kształtu

określenie w jaki sposób obiekty są ze sobą skomponowane

(26)

Java 2D vs AWT

public void paint(Graphics g) { // ustawianie atrybutów pędzela g.setColor(someColor);

g.setFont(someLimitedFont);

// kreślenie kształtów g.drawString(…);

g.drawLine(…)

g.drawRect(…); // outline g.fillRect(…); // solid

g.drawPolygon(…); // outline g.fillPolygon(…); // solid g.drawOval(…); // outline g.fillOval(…); // solid //etc…

}

public void paintComponent(Graphics g) { // czyszczenie obrazu

super.paintComponent(g);

// rzutowanie kontekstu na konteskt Java2D Graphics2D g2d = (Graphics2D)g;

// Set pen parameters

g2d.setPaint(fillColorOrPattern);

g2d.setStroke(penThicknessOrPattern);

g2d.setComposite(someAlphaComposite);

g2d.setFont(anyFont);

g2d.translate(…);

g2d.rotate(…);

g2d.scale(…);

g2d.shear(…);

g2d.setTransform(someAffineTransform);

// definiowanie własnego kształtu SomeShape s = new SomeShape(…);

// rysowanie kształtu g2d.draw(s); // outline g2d.fill(s); // solid }

(27)

Figury podstawowe - rysowanie (1)

Java 2D API udostępnia podstawowe kształty: linia, punkt, prostokąt, etc…

w pakiecie java.awt.geom

Klasy reprezentujące kształty implementują interfejs

Shape: pozwala opisać krzywą

PathIterator: określa w jaki sposób są pobierane elementy krzywej.

Należy uzyskać obiekt typu Graphics2D

Każda funkcja wymaga zdefiniowana punktu zaczepienia

np. java.awt.Graphics.drawLine(int x1, int y1, int x2, int y2).

(x1, y1) początek linii, a (x2, y2) koniec linii.

Jeśli chcemy narysować kształt z Java 2D możemy użyć funkcji draw

g2.draw(new Line2D.Double(x1, y1, x2, y2));

lub Line2D.Float(float X1, float Y1, float X2, float Y2) ;

(28)

Figury podstawowe - rysowanie (2)

Krzywe kwadratowe:

QuadCurve2D

Metoda setCurve – pozwala na określenie dwóch punktów

końcowych oraz punktu sterującego krzywą

Krzywe sześcienne:

CubicCurve2D

Kawałek parametryzowanej krzywej sześciennej

Metoda setCurve analogiczna do metody setCurve z krzywej kwadratowej poszerzona o drugi punkt kontrlony

QuadCurve2D q =

new QuadCurve2D.Float();

q.setCurve(0, 0, 200, 600, 400, 0);

g2d.draw(q);

CubicCurve2D q =

new CubicCurve2D.Float();

q.setCurve(0, 0, 50, 50, 10,100, 400, 0);

g2d.draw(q);

(29)

Figury podstawowe - rysowanie (3)

Klasa Rectangle dziedziczy po RectangularShape i

implementuje interfejs Shape oraz kilka dodatkowych metod pozwalających na określenie położenia, rozmiaru, środka, etc…

Klasa RoundRectangle definiuje prostokąt z zaokrąglonymi

wierzchołkami.

Do wyspecyfikowania prostokąta wymagane są: położenie, wysokość, szerokość, wartość wysokości kąta zaokrąglenia, wartość szeorkości kąta zaokrąglenia

(30)

Figury podstawowe - rysowanie (4)

Elipsa – krzywa zdefiniowana w typie Ellipse2d

Do narysowania wymagana jest położenie oraz wysokość i szerokość

Łuk – część elipsy. Zdefiniowana w klasie Arc2D. Do opisania potrzebne jest: położenie, wysokość i szerokość prostokąta w który jest wpisana elipsa, początek i koniec kąta, typ zamknięcia.

Typy zamknięcia: OPEN, PIE, CHORD

g2.draw(new Ellipse2D.Double(x, y,

rectwidth, rectheight));

g2.draw(new Arc2D.Double(x, y,

rectwidth,

rectheight, 90, 135,

Arc2D.OPEN));

(31)

Własne kształty

Do rysowania własnych kształtów została stworzona klasa

GeneralPath.

GeneralPath implementuje

interfejs Shape i pozwala rysować krzywe, które złożone są z

podstawowych kształtów: linie, krzywe sześcienne i kwadratowe,

Metody do kształtowania GeneralPath

moveTo(float x, float y) – przesuń aktualny punkt ścieżki do danego punktu

lineTo(float x, float y) – dodaj kawałek linii do obecnej ścieżki

quadTo(float ctrlx, float ctrly, float x2, floaty2) – dodaj krzywą

sześcienną do aktualnej ścieżki.

curveTo(float ctrlx1, float ctrly1, float ctrlx2, float ctrly2, float x3, floaty3) – dodaj krzywą sześcieną do aktualnej ścieżki

int x2Points[] = {0, 90, 0, 90};

int y2Points[] = {0, 40, 40, 0};

GeneralPath lamana =

new GeneralPath(GeneralPath.WIND_EVEN_ODD, x2Points.length);

lamana.moveTo (x2Points[0], y2Points[0]);

(32)

Określenie grubości i rodzaju krawędzi (stroking) oraz wypełnienia

Wygląd kształtów możemy modyfikować po przez:

wypełnienie (filling) – wypełnianie kształtu określonym kolorem, gradientem lub wzorem

określanie krawędzi (stroking) – krawędź może mieć

grubość, kolor, styl

Ażeby narysować kształty należy zmienić przed

wywołaniem metody draw ustawienia kontsktu

Graphics2D.

Zaokrąglony prostokąt z przerywaną linią final static float przer1[] = {10.0f};

final static BasicStroke przer = new

BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,

10.0f, przer1, 0.0f);

g2.setStroke(przer);

g2.draw(new RoundRectangle2D.Double(x, y, rectWidth, rectHeight, 10, 10));

Gradient na elpisie

czerwon2bialy = new GradientPaint(0,0, color.RED,100, 0,color.WHITE);

g2.setPaint(czerwony2bialy);

g2.fill (new

Ellipse2D.Double(0, 0, 100, 50));

(33)

Style linii

Style linii są definiowane przez atrybut krawędzi dla danego kontekstu Graphics

W celu ustawienia wybranego stylu linii należy utworzyć

instancje BasicStroke i ustawić dla kontekstu Graphics za

pomocą funkcji setStroke.

Metoda draw narysuje kształt zgodnie z ustawioną definicją linii

Właściwości stylu linii:

Grubość linii

Rodzaj połączenia linii:

JOIN_BEVEL, JOIN_MITER, JOIN_ROUND

Styl zakończenia linii:

CAP_BUTT, CAP_ROUND, CAP_SQUARE

Przerywanie linii. Ażeby

zdefiniować przerywanie linii

należy określić długość części

widocznej i niewidocznej i

(34)

Wzory wypełnienia

Wzory wypełnienia są definiowane jako atrybut procesu malowania

Wybranie wzoru wypełnienia wymaga utworzenia obiektu

implementującego interfejs Paint oraz ustawienia go dla wybranego kontekstu graficznego Graphics za pomocą metody setPaint

Trzy klasy implementują interfejs Paint:

Color,

GradientPaint – określony przez punkt, w którym rozpoczyna się dany kolor oraz punkt, w którym kończy się dany kolor.

TexturePaint – definiowany przez BufferImage. Należy wskazać obraz

oraz rozmiar prostokąta z obrazem, który będzie powielany

(35)

Praca z obrazami

 Obrazy są obiektami, które posiadają wysokość i szerokość oraz własny układ współrzędnych

 Możliwe akcje do wykonania na obrazach:

 Ładowanie zewnętrznych obrazów w formatach GIF, PNG, JPEG do wewnętrznej reprezentacji obrazu w Java 2D

 Bezpośrednie tworzenie obrazu i jego renderowanie

 Bezpośrednie rysowanie zawartości obrazu na

powierzchni przeznaczonej do rysowania

(36)

Klasy związane z obrazami

 java.awt.Image – jest to klasa bazowa dla pozostałych klas związanych z obrazami

przechowująca informację o obrazie jako tablica pikseli

 java.awt.image.BufferdImage – klasa dziedzicząca po Image umożliwiająca bezpośrednią pracę nad obrazem (np.

ustawianie kolorów pikseli). Aplikacje mogą

bezpośrednio tworzyć instancję tej klasy

(37)

Klasa BufferedImage

Przeprowadzane operacje na obrazie realizowane są

bezpośrednio w pamięci

Udostępnia metody do

przechowywania, interpretacji i uzyskiwania danych

dotyczących pikseli

Może być renderowany przez Graphics lub Graphcis2D

BufferedImage określony jest przez:

Raster

Funkcje Raster’a:

Reprezentuje układ

współrzędnych związanych z obrazem

Zarządza danymi dot. obrazu bezpośrednio w pamięci

Udostępnia mechanizm tworzenia różnych

podobrazów z pojedynczego bufora z danymi o obrazie

Oferuje metody pozwalające

na dostęp do poszczególnych

pikseli obrazu

(38)

Czytanie/ładowanie obrazu

Java 2D umożliwia ładowanie obrazu z zewnętrznego formatu za pomocą

Image I/O API.

Image I/O API obsługuje następujące formaty: GIF, PNG, JPEG, BMP, WBMP

Rozpoznanie typu kodowania obrazu realizowane jest automatycznie

Wczytywanie obrazu może być

realizowane również nie tylko z pliku, ale także ze strumienia danych

Więcej informacji na temat Image I/O API:

http://java.sun.com/j2se/1.4.2/docs/g

uide/imageio/spec/imageio_guideTOC.fm .html

Przykład wczytania obrazu

BufferedImage img = null;

try {

img = ImageIO.read(new File("strawberry.jpg"));

} catch (IOException e) {}

(39)

Rysowanie obrazów

Do rysowania obrazów w danym położeniu służy funkcja:

boolean Graphics.drawImage(Image img, int x, int y, ImageObserver observer);

x, y – określają pozycję obrazu

observer informuje aplikację o fakcie załadowania obrazu w przypadku asynchronicznym. Nie jest wymagany dla BufferedImage

Obraz jest rysowany 1:1 w przestrzeni użytkownika (user space)

Przykład metody umożliwiającej rysowanie części obrazu, skalowanie oraz stosowanie filtrów:

boolean Graphics.drawImage(Image img, int dstx1, int dsty1, int dstx2, int dsty2, int srcx1, int srcy1, int srcx2, int srcy2, ImageObserver observer);

src – reprezentuje obszar, który będzie skopiowany i odrysowany

dst – określają obszar, w którym będą przerysowane dane z src

Rozmiary obrazka obliczane są analogicznie dla wysokości i szerokości w następujący sposób: srcx2-scrx1

(40)

Stosowanie filtrów

Filtrowanie danego obrazka polega na utworzeniu nowego z użyciem pewnego algorytmu modyfikującego poszczególne piksele (np. modyfikacja

kanału alpha, czyli przeźroczystości)

void

Graphics2D.drawImage(

BufferedImage img, BufferedImageOp op, int x, int y)

BufferedImageOp – klasa implementująca określony filtr

Przykładowe filtry:

ConvolveOp. Każdy z wyjściowych pikseli jest obliczany z pośród go otaczających. Może być wykorzystany do rozmywania lub wyostrzania

obrazów.

AffineTransformp. Filtr ten mapuje piksele ze źródłowej pozycji do innego położenia docelowego dokonującą transformacji na lokalizacji pikseli

LookupOp. Filtr dokonuje zamiany kolorów na podstawie dostarczonej tablicy kolorów.

RescaleOp. Filtr mnoży wartości opisujące kolor przez ten sam

współczynnik. Może być wykorzystany do rozjaśniania lub przyciemnia obrazu lub zmiany przeźroczystości.

(41)

Tworzenie i rysowanie obrazów

Dowolny obraz może być utworzony z wykorzystaniem następujący konstruktorów:

new BufferedImage(width, height, type) – konstruuje BufferedImage dla wybranego predefiniowanego typu obrazu of

new BufferedImage(width, height, type, colorModel) – konstruuje BufferedImage dla wybranego typu obrazu: TYPE_BYTE_BINARY lub TYPE_BYTE_INDEXED.

new BufferedImage(colorModel, raster, premultiplied, properties) – konstruuje nowy BufferedImage z określonym Modelem Kolorów i Rastrem.

Obraz może być stworzony nie tylko na ekranie. Obraz może być

rozważany w kontekście powierzchni po której można rysować. Do tego celu służy metoda createGraphics()

BufferedImage off_Image = new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB);

Graphics2D g2 = off_Image.createGraphics();

(42)

Podwójne buforowanie

Obraz tworzony w pamięci może być wykorzystany do budowy mechanizmu podwójnego buforowania.

Mechanizm podwójnego buforowania zmniejsza użycie zasobów dzięki czemu animacja jest płynna

W tym przypadku przetworzenie obrazu realizowane w pamięci po czym obraz jest kopiowany na ekran

Java 2D umożliwiających dostęp do mechanizmów przyśpieszających obróbkę obrazów w buforze:

Metoda getCapabilities pozwala określić, czy wyświetlanie obrazu jest przyśpieszone (accelerated).

Metoda setAccelerationPriority pozwala na ustawienie współczynnika określającego jak ważne jest przyśpieszenie wyświetlania danego obrazu

Metoda getAccelerationPriority zwraca informacje na temat priorytetu przyśpieszenia wyświetlania obrazu.

(43)

Zapisywanie obrazu

Zapisanie obrazu na dysku z BufferedImage z użyciem Image I/O API

static boolean ImageIO.write(RenderedImage im, String formatName, File output) throws IOException

Metoda ImageO.write woła plug-in dla danego typu obrazka, które nazwa przekazywana jest w parametrze formatName. Dzięki temu można łatwo rozszerzyć listę obsługiwanych formatów.

Standardowo obsługiwane formaty: JPEG, PNG, GIF, BMP i WBMP

Metoda String writerNames[] = ImageIO.getWriterFormatNames(); zwraca listę wspieranych formatów przez JRE

try {

BufferedImage bi = getMyImage();

// zapisanie obrazu

(44)

Właściwości obrazów

Format Zalety Wady

GIF

Wspiera animację i przeźroczystość Tylko 256 kolorów

PNG

Bardzo dobra alternatywa dla

kolorowych obrazów, które nie mogą być zakodowane stratnie w

porównaniu do JPG i GIF

Nie wspiera animacji

JPG

Bardzo dobry dla obrazów będących

zdjęciami. Kompresja stratna, źle się

zachowuje w przypadku kodowania tekstu, i innych rodzajów obrazu, które muszą zachować ostrość.

Cytaty

Powiązane dokumenty

Proszę zapoznać się z nowymi wiadomościami i terminami, które znajdują się pod wyżej wymienionymi

Należy uznać za poprawne wszystkie wyniki, które są konsekwencją przyjętych przez zdającego poprawnych zaokrągleń... czerwona

W równaniach reakcji, w których ustala się stan równowagi, brak „ ⇄” nie powoduje utraty punktów.. Elementy odpowiedzi umieszczone w nawiasach nie

Należy uznać za poprawne wszyst- kie wyniki, które są konsekwencją przyjętych przez zdającego po- prawnych zaokrągleń1. 1

katoda – stal lub gwóźdź stalowy. - Za napisanie wzoru trans-alkenu: Uznaje się każdy poprawny wzór, który przedstawia izomer trans. Jeśli zdający zapisze równanie reakcji

Genetycznie uwarunkowany metabolizm leków stosowanych w chorobach układu

Farmakoterapia zaburzeń przewodu pokarmowego związanych z okresem

Stąd sądzę, że ontologia jest jedną z nauk filozoficznych, które na serio winny być brane pod uwagę przez tak szczegółową naukę jak kognitywistyka.. To zaś oznacza, że