Завантаження растрового зображення

Виконується за допомогою метода getImage(). Існує декілька варіантів цього метода. Насамперед, варіант цього метода, про який, до речі, пишуть всі книжки, визначено в класі Applet:

public Image getImage(URL url, String name);

Клас URL надає URL (Uniform Resource Locator, уніфікований покажчик ресурсів), який є форматом адрес ресурсів в WWW. Другий параметр задає розташування файла зображення відносно адреси URL. Наприклад,

Image img;

img = getImage("http://www.glasnet.ru//~frolov//pic","cd.gif");

Якщо аплет бажає завантажити зображення, що розташоване в тому ж каталозі, де і він сам, це можна зробити так:

img = getImage(getCodeBase(), "pic.gif");

Метод getCodeBase(), який також належить класу Applet, повертає URL-адресу аплета. Замість нього можна використовувати метод getDocumentBase(), який повертає URL-адресу HTML-файла, що містить аплет.

img = getImage(getDocumentBase(), "pic.gif");

Якщо ви створюєте на аплет, а додаток, ліпше використовувати інший варіант getImage(), який визначено в класі Toolkit

public abstract Image getImage(String filename)

Як звернутися до цього метода (зверніть увагу, що він має один параметр)? Наведемо приклад використання getImage() для завантаження файла duke1.gif, що знаходиться в підкаталозі images поточного каталога:

img = Toolkit.getDefaultToolkit().getImage("image//duke1.gif");

За будь-яких умов метод getImage() повертає об’єкт класу Image.

Виведення зображення

Зверніть увагу! Насправді метод getImage() не завантажуєзображення через мережу, як це може здаватися. Він тільки створює об’єкт Image. Реальне завантаження файла растрового зображення буде виконуватися методом рисування drawImage(), який належить класу Graphics. Варіанти цього методу (не всі):

public abstract boolean drawImage(Image img, int x, int y,

ImageObserver observer);

public abstract boolean drawImage(Image img, int x,int y,

int width, int height, ImageObserver observer);

Перший параметр – посилання на об’єкт класу Image, який отримано раніше за допомогою getImage(). Далі x та y – координати лівого верхнього кута прямокутного регіону, в якому буде виводитись зображення. Якщо для рисування обрано метод drawImage() з параметрами width (ширина) та height (висота), зображення буде виведено з масштабуванням. Зверніть увагу! Помноживши ці параметри на коефіцієнти, можна розтягнути (стиснути) зображення по горизонталі та вертикалі. Параметр observer – це посилання на об’єкт класу ImageObserver, який отримає звістку при завантаженні зображення. Звичайно таким об’єктом є сам клас, тому цей параметр вказується як this.

Коли викликається метод drawImage() зображення ще може бути не завантажено. Оскільки процес завантаження по мережі – досить тривалий та не передбачуваний в часі, необхідно передбачити якісь засоби для контролю над цим процесом. Принаймні когось треба повідомити, коли зображення вже буде повністю завантажено, що і робиться в цих методах. Можна виводити зображення по мірі готовності, можна дочекатися повного завантаження, а вже потім виводити на екран.

Клас Image

Розглянемо детальніше методи класу Image.

Методи getHeight() та getWidth(), визначені в класі Image, дозволяють визначити відповідно висоту та ширину зображення:

public abstract int getHeight(ImageObserver observer);

public abstract int getWidth(ImageObserver observer);

Оскільки при виклику цих методів зображення ще може бути не завантажено, як параметр методам передається посилання на об’єкт ImageObserver.

Метод getGraphics() дозволяє отримати позаекранний контекст зображення для рисування зображення не у вікні додатка або аплета, а в оперативній пам’яті:

public abstract Graphics getGraphics();

Ця техніка використовується для того, щоб спочатку підготувати зображення в пам’яті, а потім за один прийом відобразити його на екрані.

 

  1. Способи усунення мерехтіння при виведенні інформації на екран.

Усунення мерехтіння

Головним чинником цього неприємного явища є те, що зображення малюється безпосередньо перед очима користувача. Ця перерисовка помітна оку та викликає ефект мерехтіння. Стандартний вихід з цієї ситуації – подвійна буферизація.

Основна ідея полягає в тому, що поза екраном (в оперативній пам’яті) створюється зображення, і все рисування відбувається саме на цьому зображенні. Коли рисування завершується, можна скопіювати зображення на екран за допомогою лише одного метода, таким чином поновлення екрану відбудеться миттєво.

Інше джерело мерехтіння – метод update(), який викликається методом repaint(). Стандартний метод update() спочатку очищує область рисування, а потім викликає метод paint(). Щоб позбавитися від цього, достатньо просто перевизначити метод update(), щоб він просто викликав метод paint():

public void update(Graphics g)

{

paint(g);

}

Але таке просте рішення містить одну небезпеку. Справа в тому, що зображення не обов’язково покриває повністю всю прямокутну область (наприклад, фігурка людини чи щось подібне). При наступному виведенні на екран ми побачимо сліди від попереднього малюнку, якщо нове зображення його повністю не покрило.

Подвійна буферизація, хоча й більш кропітка, дозволяє повністю позбавитись від мерехтіння. Спочатку треба визначити поле нашого класу типу Image, яке буде служити позаекранним зображенням:

private Image offScreenImage;

Далі в конструкторі класу додати ініціалізацію (створення) цього поля:

offScreenImage = createImage(size().width, size().height);

І, на сам кінець, треба перевизначити метод update(), щоб він не очищував екран, а дозволяв методу paint() сформувати зображення, яке потім копіюється на екран:

public synchronized void update(Graphics g)

{

if (offScreenImage == null)

offScreenImage = createImage(size().width, size().height);

Graphics offScreenGraphics = offScreenImage.getGraphics();

offScreenGraphics.setColor(getBackground());

offScreenGraphics.fillRect(0, 0, size().width, size().height);

offScreenGraphics.setColor(g.getColor());

paint(offScreenGraphics);

g.drawImage(offScreenImage, 0, 0, width, height, this);

}